1

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?

1
  • no, because __new__ is also a class method. So first time instance doesn"t exist, and the other times, instance exists. That the way the singleton is implemented. Commented Jun 3, 2018 at 19:21

2 Answers 2

5

__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.

Sign up to request clarification or add additional context in comments.

5 Comments

object.__new__ surely. object.__class__ is type and will try to create a new class, not an instance of Singleton
The 2nd time you call Singleton(), why "_instance = None" is not triggered? It is triggered in 1st call. Can you explain this part please? @Jean-François Fabre
@Dunes ooops, it works by chance, not what op wants.. wrong fix.
@NicolasS.Xu because it is stored in cls._instance. cls is your current class.
Why "_instance = None" only run once? Why 2nd time you call Singleton(), the first line of this class is skipped?
2

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

6 Comments

your are right. My mistake. If it is always true, why need a "if" after always true value?
Because you update cls._instance in the process, so that the next time around, cls._instance is no longer None, and not cls._instance is no longer True.
You said " so that the next time around, cls._instance is no longer None" . This part I don't understand. Why? I think every time, the _instance is set to None. Is it so?
@NicolasS.Xu No. _instance is a class attribute, not an instance attribute.
@NicolasS.Xu. The values of class attributes are shared between all instances, because they are stored on the class-object rather than the instance-object. Since all instances have the same class, they will all see the same class attribute values.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.