Reputation: 14544
Here is an example of singleton in python. One thing I don't understand is I think the _instance in class is always set to None, therefore the "if not cls._instance" should always true, therefore, there is no need for the if statement.
I know I am wrong, please help me where I missed.
class Singleton(object):
_instance = None # Keep instance reference
# why do this???? If do this, the "if not .." state follow is always true, right?
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__name__(cls, *args, **kwargs)
return cls._instance
Update
My confusion is: Why the 2nd time you call Singleton(), the _instance = None is not triggered? Whereas it is triggered 1st call?
Upvotes: 1
Views: 1398
Reputation: 140196
__new__
is a class method as well that supersedes the __init__
method (you have control on the object which gets created at this level)
_instance
is a class attribute, not an instance attribute. So it's visible/available in the __new__
method before an instance is created.
So first time, the cls._instance
argument is None
, so __new__
creates the instance and stores the result in the _instance
class attribute of cls
(which is your Singleton
class)
It is not None
the second time because the reference of the instance has been stored, so it returns the same self._instance
object. In the process, object.__new__
is only called once during the lifetime of the class.
This follows the design pattern of the singleton: create once, return the same object everytime.
note that this is incorrect:
cls._instance = object.__name__(cls, *args, **kwargs)
should be
cls._instance = object.__new__(cls, *args, **kwargs)
Calling object.__name__
makes no sense since it's a string. Small self-contained example derived from your code:
class Singleton(object):
_instance = None # Keep instance reference
# why do this???? If do this, the if state follow is always false, right?
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
print("creating")
return cls._instance
a = Singleton()
b = Singleton()
print(a is b)
this code outputs:
creating
True
as you see, first time it's creating the object, then it's returning the same object the second time the object is created.
Upvotes: 5
Reputation: 18201
If cls._instance
is None
, then not cls._instance
is True
, not False
.
Upvotes: 2