• 单例模式


    使用new方法实现单例模式

      每个实例的创建是通过__new__方法,所以如果要实现一个类只能有一个实例就得重写__new__函数。

    class A:
        _instance = None
        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                print("创建了一个实例")
                obj = super().__new__(cls, *args, **kwargs)
                cls._instance = obj
                return obj
            return cls._instance
    
        def __init__(self):
            print('开始初始化')

    执行:

    a = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    b = A()

    输出为:

    开始初始化

    执行:

    print(id(a), id(b))  # 每个实例的id一样

    输出:

    140078083206056 140078083206056

    使用共享属性实现单例模式

      与上一种方法不同的是,此种方法当执行__new__方法后,每次生成一个新的实例。只不过每个实例共享同样的属性,因此实际使用的效果和上面的方法一样。但严格意义上讲,我认为这不算单例。

    class A:
        _myDict = {}
        def __new__(cls, *args, **kwargs):
            obj = super().__new__(cls, *args, **kwargs)
            obj.__dict__ = cls._myDict
            print("创建了一个实例")
            return obj
        
        def __init__(self):
            print("开始初始化")

    执行:

    a = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    b = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    print(id(a), id(b))  # 每个实例的id不一样

    输出为:

    140078082716952 140078082716504

    执行:

    a.a = '1'  # 此时对实例a添加一个a属性
    
    pirnt(b.a)  # 通过b得到了与a一模一样的值

    使用装饰器实现单例模式

      装饰器的特色就是给函数添加额外的功能,同样可以在类上使用装饰器,来限制实例的个数。但此种方法与上两种不同的是,前两种类的__init__方法在生成实例后都被执行了执行了一次,而此种方法只有在第一次生成实例时才调用__init__方法。

    def oneObject(cls):
        def wrap(*args, **kwargs):
            if not hasattr(cls, '_instance'):
                obj = cls(*args, **kwargs)
                cls._instance = obj
                return obj
            return cls._instance
        return wrap
    
    
    
    @ oneObject
    class A:
        def __init__(self):
            print("已经创建了一个实例")

    执行:

    a = A()

    输出为:

    已经创建了一个实例

    执行:

    b = A()  # 注意,没有执行__init__函数

    print(id(a), id(b))

    输出为:

    140357050460928 140357050460928
     
  • 相关阅读:
    HDU 2895 编辑距离
    AC自动机
    HDU 1707 简单模拟 Spring-outing Decision
    HDU 1710 二叉树的遍历 Binary Tree Traversals
    Codeforces Round #521 (Div. 3) E. Thematic Contests
    Codeforces Round #521 (Div. 3) D. Cutting Out
    Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum
    Codeforces Round #510 (Div. 2) B. Vitamins
    Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
    Codeforces Round #506 (Div. 3) 题解
  • 原文地址:https://www.cnblogs.com/zhouyang123200/p/6538305.html
Copyright © 2020-2023  润新知