• 创建型模式之单例模式


    单例模式确保应用程序中始终只有一个存活的实例。例如你想要资源访问限制的时候,或者数据库连接类等等,再比如服务配置文件放在一个目录中,程序启动需要通过Configure类加载配置文件。如果每个程序都去实例化一个Configure类,尤其conf文件还比较大

    这个时候就会造成内存浪费,这种情况单例模式就派上用场了。

    单例模式有如下几种实现方式

    1.使用带有函数或者变量的模块,如数据库连接的的配置文件

    MONGODB = "xxx"
    MYSQL = "xxx"
    REDIS = "xxx"

    将它们保存在settings.py的文件中,然后其他程序直接导入即可,python这种导入本身就是单例模式的实现。

    from settings import MONGODB

    如果需要单例的类就实例化

    class Singleton(object):
        pass
    
    singleton = Singleton()

    然后导入实例化之后的方法就可以了

    from xxx import singleton

    2.使用单例模糊的装饰器

    def Singleton(cls):
        cls_instance = {}
        def is_instance(*args, **kargs):
            if cls not in cls_instance:
                cls_instance[cls] = cls(*args, **kargs)
            return cls_instance[cls]
        return is_instance
    
    @Singleton
    class SingletonTest(object):
    
        def __init__(self, v):
            self.value = v
    
    t = SingletonTest(2)
    t2 = SingletonTest(3)
    print(t.value, t2.value)
    print(id(t) == id(t2))

    >>> 2, 2
    >>> True

    3.使用__new__实现

    在类实例化的时候,python首先调用__new__方法,然后在执行__init__进行初始化。所以我们可以在__new__做手脚。

    class Singleton(object):
        _instance = None
    
        def __new__(cls, *args, **kwargs):
            if cls._instance is None:
                cls._instance = super().__new__(cls, *args, **kwargs)
            return cls._instance
    
    t1 = Singleton()
    t2 = Singleton()
    print(id(t1) == id(t2))
    >>> True

    注意: 这样写非常危险,如果你已经创建了一个基类,然后你尝试对基类的子类进行实例化,这个时候问题就出现了。

    结果都会依赖实例创建的顺序,父类先创建就会出问题,子类先创建就是正常的。在大型应用中这是难以预测的错误千万要注意。如果单例不会被子类实例化,这个方法就没有问题。

    4.使用元类实现

    class Singleton(type):
        _intances = {}
        def __call__(cls, *args, **kwargs):
            print(cls._intances)
            if cls not in cls._intances:
                cls._intances[cls] = super().__call__(*args, **kwargs)
            return cls._intances[cls]
    
    class SingletonTest(metaclass=Singleton): # 指定创建Foo的type为SingletonType
        def __init__(self, v):
            self.value = v
    
    
    obj = SingletonTest('xx')
    obj2 = SingletonTest('xxx')
    print(id(obj) == id(obj2))
    print(obj.value, obj2.value)

    通常我们实例化都会生成一个新实例

    1 class Singleton(object):
    2     pass
    3 
    4 a = Singleton()
    5 b = Singleton()
    6 print(id(a) == id(b))
    >>> False
  • 相关阅读:
    数据库Mysql给用户赋予操作表的权限
    C# log4net日志分等级打日志
    C# 将字符串转为函数名
    C# winform无法拖动控件
    C# 程序获取管理员方法
    C# 生成程序目录避免生成多余的XML和pdb
    C# 快速获取一个月的天数或最后一天
    正则
    C# 根据服务名打开所在文件夹
    330 div+css Experience
  • 原文地址:https://www.cnblogs.com/Leonharetd/p/9497948.html
Copyright © 2020-2023  润新知