Skip to content

Instantly share code, notes, and snippets.

@werediver
Created December 28, 2012 09:51
Show Gist options
  • Save werediver/4396488 to your computer and use it in GitHub Desktop.
Save werediver/4396488 to your computer and use it in GitHub Desktop.
A thread safe implementation of singleton pattern in Python. Based on tornado.ioloop.IOLoop.instance() approach.
import threading
# Based on tornado.ioloop.IOLoop.instance() approach.
# See https://github.com/facebook/tornado
class SingletonMixin(object):
__singleton_lock = threading.Lock()
__singleton_instance = None
@classmethod
def instance(cls):
if not cls.__singleton_instance:
with cls.__singleton_lock:
if not cls.__singleton_instance:
cls.__singleton_instance = cls()
return cls.__singleton_instance
if __name__ == '__main__':
class A(SingletonMixin):
pass
class B(SingletonMixin):
pass
a, a2 = A.instance(), A.instance()
b, b2 = B.instance(), B.instance()
assert a is a2
assert b is b2
assert a is not b
print('a: %s\na2: %s' % (a, a2))
print('b: %s\nb2: %s' % (b, b2))
@sheldonldev
Copy link

sheldonldev commented Mar 2, 2024

@jhcloos seems cool!

But it would be like this:

if __name__ == '__main__':
	class A(SingletonMixin):
		pass

	class B(SingletonMixin):
		pass

	a, a2 = A.instance(), A.instance()
	b, b2 = B.instance(), B.instance()

	assert a is a2
	assert b is b2
	assert a is not b  # <== as a result, a is b in this case

	print('a:  %s\na2: %s' % (a, a2))
	print('b:  %s\nb2: %s' % (b, b2))

@jhbuhrman
Copy link

@sheldonldev - I don't understand what you mean. If I use my SingeletonMixin just like you do in your example above, and I enter ...

>>> a = A.instance()
>>> a2 = A.instance()
>>> a is a2
True
>>> b = B.instance()
>>> a is b
False

... that's exactly the behaviour that we would like to see, right?

@sheldonldev
Copy link

sheldonldev commented Mar 2, 2024

@sheldonldev - I don't understand what you mean. If I use my SingeletonMixin just like you do in your example above, and I enter ...

>>> a = A.instance()
>>> a2 = A.instance()
>>> a is a2
True
>>> b = B.instance()
>>> a is b
False

... that's exactly the behaviour that we would like to see, right?

@jhbuhrman Oh~~ I see. I use 'class' instead of 'cls', so I got all the same singleton! You are right. That's my fault, hh~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment