Reputation: 65
I try to implement singleton pattern in python 2 but it doesn't work, but it works in python 3, someone help me explain why?
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1)
print(obj2)
output:
<__main__.Singleton instance at 0x7fab8b625e60>
<__main__.Singleton instance at 0x7fab8b5e4710>
Upvotes: 0
Views: 844
Reputation: 514
First of all in python2 you must be inherited from object to make __new__
magic works.
Because old-style class doesn't have __new__
method at all.
So with added prints you will got:
>>> class Singleton:
... _instance = None
... def __new__(cls):
... print('__new__')
... if cls._instance is None:
... print('create')
... cls._instance = super().__new__(cls)
... return cls._instance
...
>>> obj1 = Singleton()
>>> obj2 = Singleton()
>>>
>>> print(obj1)
<__main__.Singleton instance at 0x7f47dcccecb0>
>>> print(obj2)
<__main__.Singleton instance at 0x7f47dcccef80>
As you can see python2 doesn't call __new__
at all. It just calls empty __init__
in your case and creates two different objects.
Secondly, in python2 you need rewrite super()
call as it was changed in python3.
So corrected code will be:
>>> class Singleton(object):
... _instance = None
... def __new__(cls):
... print('__new__')
... if cls._instance is None:
... print('create')
... cls._instance = super(Singleton, cls).__new__(cls)
... return cls._instance
...
>>> obj1 = Singleton()
__new__
create
>>> obj2 = Singleton()
__new__
>>>
>>> print(obj1)
<__main__.Singleton object at 0x7f47dccd9590>
>>> print(obj2)
<__main__.Singleton object at 0x7f47dccd9590>
For more information about singletons you can reed here: Creating a singleton in Python
Upvotes: 1