Singleton design pattern in Python

Singleton mode

In actual development, although the classes we may write are called (or instantiated) many times, we hope that the instantiated objects are the same object, that is, the memory space occupied is the same block of memory space, so we need to use the singleton mode.

For example, in the music player software, we can only play one song at a time. In the printer program, the printer can only have one document printed at a time. These all require the use of the singleton design pattern.

So how to design the singleton pattern?

The initialization process of Python classes is divided into two steps:

  1. Call__ new__ Method to allocate memory space and return a reference to memory space
  2. Call__ init__ Method to initialize an object in the allocated memory space

Let's take a look at the class instantiation process through a piece of code

class ClassInit(Object):
    def __new__(cls, *args, **kwargs):
        print("Allocate space")
        instance = super().__new__(cls)
        return instance

    def __init__(self):
        print("I am the initialization method")

if __name__ == '__main__':
    ci1 = ClassInit()
    print(ci1)
    ci2 = ClassInit()
    print(ci2)
# ___________________The The results are as follows:______________________
Allocate space
 I am the initialization method
<__main__.ClassInit object at 0x10131da50>
Allocate space
 I am the initialization method
<__main__.ClassInit object at 0x10131db70>

In the above example, we override the__ new__ Method and called the__ new__ Method returns an instance object, which will be called later__ init__ Method to instantiate a class. In lines 11-14 of the above example, we can also see that we have created two class instances, and the memory addresses of the printed class instances are also different, that is, the above methods are not in the singleton mode.

In the above example, if we annotated lines 4 and 5, the returned results will be as follows:

Allocate space
None
 Allocate space
None

We override the__ new__ Method, only four words of allocated space are printed, but the__ new__ Method, the memory space cannot be allocated, and the following classes cannot be initialized, so the print class is None

Through understanding the above examples, we know that the Python compiler will automatically call the__ New__ Method to allocate memory space. Then we will consider this idea. We can judge whether we can achieve the effect of singleton mode without creating new instances when the memory space (instance object) already exists?

We can define a class attribute with an initial value of None when calling__ new__ Method, we first determine whether the class attribute is None, and then we allocate memory space. See the following example:

class ClassInit:
    instance = None
    def __new__(cls, *args, **kwargs):
        print("Allocate space")
        if cls.instance is None:
            cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self):
        print("I am the initialization method")

if __name__ == '__main__':
    ci1 = ClassInit()
    print(ci1)
    ci2 = ClassInit()
    print(ci2)
# ___________________The The results are as follows:______________________
Allocate space
 I am the initialization method
<__main__.ClassInit object at 0x10b6e1a90>
Allocate space
 I am the initialization method
<__main__.ClassInit object at 0x10b6e1a90>

In line 2, define a class attribute instance and assign the initial value to None

In line 5, judge whether the class attribute instance is None. If it is None, call the__ new__ Method, allocate memory space, and assign a reference to the memory space to the class attribute instance.

Line 7, and finally return the class attribute. That is, the reference of the allocated memory space

Finally, look at the execution results. We called class instantiation twice, but the memory space addresses of the instantiated objects of the two classes printed are the same, that is, they are the same instance of the same class. In this way, the design requirements of the singleton pattern are met.

Tags: Python

Posted by statrat on Mon, 30 May 2022 07:39:34 +0530