class Singleton:
instance = None
def __new__(cls):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
singleton_obj1 = Singleton()
singleton_obj2 = Singleton()
print(singleton_obj1)
print(singleton_obj2)
output
<__main__.Singleton object at 0x10dbc0f60>
<__main__.Singleton object at 0x10dbc0f60>
Can someone explain what exactly happening at this line cls.instance = super().__new__(cls)
. Which lines of code helped to make this class Singleton
?
Ok, to go over this in painful detail:
class Singleton:
implicitly inherits from Object
because in python everything is an Object.
instance = None
is only read at module load time, and sets the class level variable instance
to be None
one time but it can be over written by individual instances of the class Singleton
.
def __new__(cls):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
(First off, I think that it's weird that they put "cls" in there, I know why they did it, because it's referring to the class overall and not a specific instance of that class. But, it can be confusing so someone who doesn't know what they're looking at. Anyway...)
__new__
is a magic function that is called before __init__
, that is roughly analogous to allocating the space for the new instance of the class. Here, cls.instance
was set to None
on module load, and so every time a new Singleton
is being created this test is done. Since cls.instance
is set the first time a Singleton
is created, the super().__new__(cls)
is also only called once. The super class of Singleton
is Object
. So the behavior of the super().__new__(cls)
is exactly what you'd expect it to be for any other class you create.
If, you are creating a second(, or third/fourth/fifth...) instance of Singleton
then this super().__new__(cls)
will not be called. Instead the class level variable instance
is returned, meaning that no new instances of Singleton
can be created.
When you print the instances of Singleton
then you can see the memory address of 0x10dbc0f60
is the same for both "instances" because cls.instance
is returned at __new__
time, which you can think of as memory allocation time, before __init__
is called.
This is a good way to do a Singleton pattern because in order to create a singleton class, now, all you have to do is inherit from Singleton
and the heavy lifting is already done. You go ahead and use __init__
like you normally would, and don't worry about it. Every time you go to create a "new" instance of that class, you'll get the same instance back. Totally behind the scenes.
This is pretty advanced stuff, but look how simple it is. python is the best!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With