On the simple interest model and its application scenarios (Python)

python interest in single mode

Usage scenarios:
+ Python's logger is a singleton for logging
+ Windows Explorer is a singleton
+ thread pools, database connection pools resource pool generally use a singleton
+ website counter

From these usage scenarios we can summarize singleton needs under what circumstances:

   1. 当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次;
   2. 当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题。
  1. __new__ way to achieve
    class Singleton(object):
        __instance = None
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
                # 可以在这里给实力对象绑定一些固有属性
                # cls.__instance.appkey = ""
            return cls.__instance
  • 1.1
    class Singleton(object):
        def __new__(cls, *args, **kwargs):
            # 判断是否存在类属性_instance,_instance是类CCP的唯一对象,即单例
            if not hasattr(Singleton, "__instance"):
                cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
                # cls.__instance = object.__new__(cls)
                return cls.__instance

However, the above methods have multiple threads thread-safety issues, when there are multiple threads to initialize the object, it is possible to simultaneously determine __instance is None, to enter the instance initialization code (if there is __init__ method) . It is necessary to use a mutex to solve this problem.

  1. Implement a thread-safe singleton
    import threading
    try:
        from synchronize import make_synchronized
    except ImportError:
        def make_synchronized(func):
            import threading
            func.__lock__ = threading.Lock()

            # 用装饰器实现同步锁
            def synced_func(*args, **kwargs):
                with func.__lock__:
                    return func(*args, **kwargs)

            return synced_func


    class Singleton(object):
        __instance = None

        @make_synchronized
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                cls.__instance = object.__new__(cls)
            return cls.__instance

        def __init__(self):
            self.blog = "blog"

    # -------------
    def worker():
        e = Singleton()
        print(id(e))


    def meta():
        e1 = Singleton()
        e2 = Singleton()
        e1.blog = 123
        print(e1.blog)
        print(e2.blog)
        print(id(e1))
        print(id(e2))


    if __name__ == "__main__":
        meta()
        tasks = [threading.Thread(target=worker) for _ in range(20)]
        for task in tasks:
            task.start()
            task.join()
  1. Decorator singleton object to obtain
    # 装饰器(decorator)可以动态地修改一个类或函数的功能
    import functools
    def singleton(cls):
        __instance = {}
        @functools.wraps(cls)
        def getinstance(*args, **kwargs):
            if cls not in __instance:
                __instance[cls] = cls(*args, **kwargs)
            return __instance[cls]
        return getinstance

    @singleton
    class MyClass(object):
        a = 1 

We define a decorator singleton, it returns an internal function getinstance, the function will determine whether or not a class in the dictionary instances, if not present, it will be cls as a key, cls (* args, ** kw) as value stored in the instances, or directly back instances [cls].

  1. Use metaclass metaclass to create a singleton
    metaclass (metaclass) can control the process of creating the class, it is mainly to do three things:
    • Creating interception class
    • Modify the definition of the class
    • Returns the modified class
    class Singleton(type):
        __instances = {}
        def __call__(cls, *args, **kwargs):
            if cls not in cls.__instances:)
                cls.__instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
            return cls.__instances[cls]
    # python2写法
    # class MyClass(object):
    #     __metaclass__ = Singleton()

    # python3写法
    class MyClass(metaclass=Singleton):
        def __init__(self):
            self.blog = "blog"

Reference:
the Python is a singleton
design pattern (Python) - Singleton

Guess you like

Origin www.cnblogs.com/panlq/p/12355917.html