Nicolas S.Xu
Nicolas S.Xu

Reputation: 14544

python singleton code

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

Answers (2)

Jean-François Fabre
Jean-François Fabre

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

fuglede
fuglede

Reputation: 18201

If cls._instance is None, then not cls._instance is True, not False.

Upvotes: 2

Related Questions