[Notes] python singleton pattern (the Singleton) and implementation

 

1. singleton design pattern

Design patterns and the single design pattern concept:

  • Design Patterns

    • Design patterns  are  summarized previous work and refining , generally, people are widespread models are designed for  a particular problem  sophisticated solutions
    • Use  design patterns  to reusable code, make the code easier to understand others, to ensure the reliability of the code
  • Singleton design pattern (Singleton Pattern)

    • The purpose  - to make  the class  objects created in the system  only only one instance exists
    • Each execution  类名() object returned, the memory address is the same

Scenarios: when the system appears only one instance of a class, can be used singletons. Objects such as the Recycle Bin, the printer object ...

 

Example 2. Single mode implementations

In python, there are many ways to implement singleton pattern.

 

2.1. Use implement __new__ method (recommended)

__New__ method described, override __new__ method, to achieve a single embodiment.

 

1.__new__ Methods  Introduction:

  • Use  the class name ()  When you create an object, Python the interpreter  first  calls the  __new__ method for the object  allocation of space , the returned object references
    • __new__ A is a  object provided base class  built-in static method , there are two major role:
      • 1) for the object in memory  space allocated
      • 2)  returns the  object reference
  • Python Obtained interpreter object  reference  , the reference as the  first parameter passed to the  __init__ method. That is, when an object is instantiated, first call __new__ method, and then call the __init__ method.

__New__ use when implementing the singleton approach is to ensure that its allocated memory space, never will return only a fixed memory space.

 

2. first understand rewrite __new__ method :

  • The method of rewriting of code is fixed __new__;
  • Rewrite __new__ method  must  return Super () .__ new new __ (CLS) , otherwise the Python interpreter  lack  of space allocated  object reference , it will not call the initialization method of the object;
  • Note: __new__ is a static method, you need to call upon  the initiative passed cls  parameters.

 

Rewrite __new__ method demo

class MusicPlayer(object):

    def __new__(cls, *args, **kwargs):

        # 1. 创建对象时,new方法会被自动调用
        print("创建对象,分配空间")

        # 2. 为对象分配空间
        instance = super().__new__(cls)

        # 3. 返回对象的引用 :super().__new__(cls)
        return instance

    def __init__(self):
        print("播放器初始化")


# 创建播放器对象
player = MusicPlayer()

print(player)

Export

创建对象,分配空间
播放器初始化
<__main__.MusicPlayer object at 0x7fdf44e0da20>


3. The  single-Example

  • Define a  class attribute instance, used to record  a single object reference embodiment, the initial value of None;
  • Define a class attribute init_flag  flag is  executed initialization operation , the initial value False;
  • __init__ Method, it is determined  init_flag, if  False it is to perform initialization operation. Then  init_flag set True;
  • __new__ Method, if  the class property is None , call the parent class method of allocating space, and the class attribute record results;
  • Returns the  class attribute  recorded in the  object reference.

In this way, ensure the  automatic  call  __init__ when the method, an initializing operation is only called once  . Operating allocated space will only execute once the object, the class created in the system  only  only one instance.

class MusicPlayer(object):

    # 记录第一个被创建对象的引用
    instance = None
    # 记录是否执行过初始化动作
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否是空对象
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance

    def __init__(self):

        if not MusicPlayer.init_flag:
            print("初始化音乐播放器")

            MusicPlayer.init_flag = True


# 创建多个对象
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

Output:

初始化播放器
<__main__.MusicPlayer object at 0x7fe266442a58>
<__main__.MusicPlayer object at 0x7fe266442a58>

 

2.2 Use metaclass manner

1. Knowledge:

Metaclass metaclass create a class, the class creates an instance of an object . Behind Python type is used to create all kind of metaclass .

When defining a class, you can add its __metaclass__ properties . Knowledge can refer  __metaclass__ property  .

Method metaclasses __call__:  https://blog.csdn.net/qq_23996069/article/details/104594802

 

__Metaclass__ properties may be utilized, metaclass, intervene when creating custom class, so as to achieve a single embodiment.

class Singleon(type):
    
    _instance = {}
    
    def __call__(cls,*args, **kwargs):
        # print("%s" % instance)
        if cls not in cls._instance:
            # 通过'type'来做类对象的创建
            cls._instance[cls] = super(Singleon,cls).__call__(*args, **kwargs)
        return cls._instance[cls]



class MusicPlayer(object, metaclass=Singleon):
    init_flag = False
    def __init__(self):
        if not MusicPlayer.init_flag:
            print("init music player.")
            MusicPlayer.init_flag = True
            

player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

# 输出:
# init music player.
# <__main__.MusicPlayer object at 0x7f403695f6d8>
# <__main__.MusicPlayer object at 0x7f403695f6d8>

 

More ways to be continued

 

 

 

 

-----end-----

Published 50 original articles · won praise 10 · views 6602

Guess you like

Origin blog.csdn.net/qq_23996069/article/details/104566784