1

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
ManuCF
  • 61
  • 6
  • Does this answer your question? [Difference between static class and singleton pattern?](https://stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern) – Be Chiller Too Nov 15 '21 at 10:14
  • 2
    What part are you having difficulty with? Do you understand what `__new__` is? Do you understand what `super` is? Do you understand what a dict is and how it works? – khelwood Nov 15 '21 at 10:15
  • @khelwood As far as I know, __new__ is going to be called when a Singleton object is created, and super is refering to the parent class __new__ method. (Am I right?) I think I'm gettin lost in inheritance flow. For example, what will be the parent class of Singleton class? object? What is object exactly? – ManuCF Nov 15 '21 at 10:26

2 Answers2

1

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

khelwood
  • 55,782
  • 14
  • 81
  • 108
  • Thanks. I can see It much clearer now. There is one thing that confuses me. Why it uses Its parent's __new__ method (which I understand the parent is "object", which is the root class they all inherit from in python, right?) – ManuCF Nov 15 '21 at 16:14
  • The superclass's `__new__` method is what Singleton's `__new__` method is overriding. If it wants the instantiation to go ahead, it falls back on the default behaviour, which is the thing it overrode, to create the instance. – khelwood Nov 15 '21 at 16:28
1

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135