Reputation: 841
What is the difference between this two implementations of Singleton. Does creating of variable _instance in parent class make it work differently from the second class?
class SingletonA(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
class SingletonB(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
# sample usage
class A(SingletonA):
pass
print(A() == A()) #True
Upvotes: 1
Views: 48
Reputation: 2255
Agreed with @Martijin Pieters answer,
Besides, provide another way to implement Singleton, called Borg, which share the same state:
class Borg:
_shared_state = {}
def __new__(cls, *args, **kwargs):
obj = super(Borg, cls).__new__(cls, *args, **kwargs)
obj.__dict__ = cls._shared_state
return obj
class S1(Borg):
pass
class S2(Borg):
pass
assert S1() is not S1()
S1().v = 1
assert S1().v == S1().v
assert S1().v == S2().v
class S3(Borg):
# if want to have a different state
_shared_state = {}
pass
S3().v = 2
assert S3().v != S1().v
Upvotes: 1
Reputation: 1122552
For the code posted, there is no difference.
If your subclasses implement __bool__
or __len__
however, the first example will fail, as not self._instance
could return True
even when an instance has been set. You really want to use if self._instance is None:
instead:
>>> class AlwaysFalse(object):
... def __bool__(self): return False
...
>>> if not AlwaysFalse():
... print("It doesn't exist? Should we create a new one?")
...
It doesn't exist? Should we create a new one?
>>> AlwaysFalse() is None
False
Other than that, the differences are cosmetic.
You also want to use identity testing to check if a singleton implementation work correctly; a subclass could implement the __eq__
method and return True
even if the two objects are distinct (so not singletons):
>>> class EqualNotSingleton(object):
... def __eq__(self, other): return True
...
>>> EqualNotSingleton() == EqualNotSingleton()
True
>>> EqualNotSingleton() is EqualNotSingleton()
False
Upvotes: 6