Issue
I've found one of most popular approach to create singleton classes, using _instance and overriding __new__ method. Here it is:
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
But it acting weird when I try to use it this way:
class Child(Singleton):
def __init__(self):
self.a = random.randint(10, 1000)
x = Child()
y = Child()
print(x.__dict__) # {'a': 74}
print(y.__dict__) # {'a': 74} - not weird
print(Child().__dict__) # {'a': 222} - weird (for me)
Can someone explain why it happens?
PS: I'm using python 3.10
Solution
An answer
In order to create an object, Python first calls __new__
on its class, then calls __init__
on the object.
When you "create" an instance of Child
, Python will call Singleton.__new__
and then Child.__init__
. But Singleton.__new__
always returns the same object, _instance
, so Child.__init__
will always re-initialise the same object.
x
and y
contain the same object, because all Child
s are the same object. That's why x.__dict__
and y.__dict__
are the same. But when you call Child
the third time, it reinitialises the object, changing its dict. print(Child().__dict__)
gives a different value because it calls Child
before printing.
It's not that the third call to Child
produces a different object; rather that the object itself changes.
Some notes on singletons
You shouldn't use __init__
if you're implementing a singleton in this way, because it will be called every time Child
is called and reinitialise the object. If you need to initialise values of the singleton, you can do so in __new__
, within the if statement, so that the initialisation is only done once.
Also consider why you need to create a subclass of a singleton. A singleton should only ever have one member, so if there are any instances of Child
, it must be that all Singleton
s are Child
s, and so Singleton
and Child
might as well be merged into one class.
Answered By - Anonymous12358
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.