Python单例模式五大实现方法

单例模式:确保类有且只有一个特定类型的对象,并提供全局访问点。

作用:程序运行过程中其实只有一个实例在运行;避免资源消耗及保证数据安全与全局性等。

场景:全局服务器配置;数据库连接;日志文件共享…

实现方式:

一. 模块

01.把函数与数据写入模块,实现单例对象
# singleton_by_module.py
class Singleton(object):
    def foo(self):
        pass


singleton = Singleton()
02.使用时直接导入/单例模式对象=singleton_by_module.py
# test.py
from singleton_by_module import Singleton

t = Singleton()

二. 装饰器

# singleton_by_decorator.py
def Singleton(cls):
    _instance = {
    
    }

    def _singleton(*args, **kwargs):
        if cls not in _instance:
            print('get ready init')
            _instance[cls] = cls(*args, **kwargs)
            print('get ready success')
        else:
            print('already init')
        return _instance[cls]

    return _singleton


@Singleton
class A(object):
    def __init__(self, a=0):
        self.a = a


a1 = A(1)
a2 = A(2)
print("a1_id:{},a1.a:{}".format(id(a1), a1.a))
print("a2_id:{},a2.a:{}".format(id(a1), a1.a))
01.程序运行:创建类对象a1调用,正常打印;当a1创建并调用由于实例已存在,调用a1,所以说他们的内存id一样。

三. 类

01.使用线程锁解决线程问题
import time
import threading
class Singleton:
    _instance_lock = threading.Lock()

    def __init__(self):
        time.sleep(1)

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance

def task(arg):
    obj = Singleton.instance()
    print(obj)
for i in range(10):
    t = threading.Thread(target=task,args=[i,])
    t.start()
time.sleep(20)
obj = Singleton.instance()
print(obj)

四.new方法

01.类实例前先执行new方法 ;然后执行init方法。
import threading
class Singleton:
    _instance_lock = threading.Lock()

    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = super(Singleton,cls).__new__(cls,*args, **kwargs)
        return Singleton._instance

obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)

def task(arg):
    obj = Singleton()
    print(obj)

for i in range(5):
    t = threading.Thread(target=task,args=[i,])
    t.start()

五.metaclass元类

01.类由type创建,创建类时,type的init方法自动执行,类() 执行type的call方法(类的new方法,类的init方法) 
02.对象由类创建,创建对象时,类的init方法自动执行,对象()执行类的call方法 
import threading

class SingletonType(type):
    _instance_lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with SingletonType._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
        return cls._instance

class Foo(metaclass=SingletonType):
    def __init__(self,name):
        self.name = name

obj1 = Foo('name')
obj2 = Foo('name')
print(obj1,obj2)

单例模式优缺点:

优点:全局只有一个实例,节省内存空间;避免开销;避免多重复用。
缺点:可扩展性差;违背单一原则;不利于测试。

猜你喜欢

转载自blog.csdn.net/weixin_44053341/article/details/113388811