Reputation: 61
I'm using this Singleton pattern and it works, but I can't figure out what it is doing. Could someone explain to me how this program works?
Thanks!
class Singleton(object):
_instances = {}
def __new__(class_, *args, **kwargs):
if class_ not in class_._instances:
class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
return class_._instances[class_]
class Context(Singleton):
#do things
Upvotes: 1
Views: 79
Reputation: 194
The singleton pattern refers to a class that you can only initiate once. If you try to create a second object of a singleton class, it will just return the already initiated object
Let's analyze the code a little step by step
_instances = {}
This is a dictionary where we save the objects we have already created. An important thing to understand here is that this is shared among the objects. When you create a new object you always get the same dictionary.
if class_ not in class_._instances:
class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
Now as I mentioned before, singleton creates an object once and it returns it again if you try to create a new object. This code here checks if we have already created the object by looking inside of the dictionary. If we haven't created it it will create a new object and it will save it to the _instances dictionary. If it already exists it will just skip this code.
return class_._instances[class_]
We then return the object that it is guaranteed to be there. Remember that we have already checked that we haven't created an instance of this class so we can create a new one. If it was already created, we just return it from the dictionary.
Upvotes: 1
Reputation: 59112
__new__
is called when you try and instantiate a particular class.
When you try and instantiate a Context, it uses the __new__
method defined in Singleton. This method first looks to see if the class (Context) has an entry in Singleton's _instances
dictionary.
If it hasn't, then a new instance is created using super(Singleton, class_).__new__(class_, *args, **kwargs)
. This is calling the __new__
method in object
: the default __new__
method that normally creates new instances. It gets a new instance of Context from that, and stores it in the _instances
dictionary, linked to the Context class, so it can look it up next time.
If it has, then the Context class has already been instantiated, so we can get the instance from the dictionary and return it.
Upvotes: 1