代码之家  ›  专栏  ›  技术社区  ›  lch

解释python singleton类

  •  3
  • lch  · 技术社区  · 6 年前
    class Singleton:
    
        instance = None
    
        def __new__(cls):
            if cls.instance is None:
                cls.instance = super().__new__(cls)
            return cls.instance
    
    singleton_obj1 = Singleton()
    singleton_obj2 = Singleton()
    
    print(singleton_obj1)
    print(singleton_obj2)
    

    输出

    <__main__.Singleton object at 0x10dbc0f60>
    <__main__.Singleton object at 0x10dbc0f60>
    

    有人能解释一下这条线上到底发生了什么吗 cls.instance = super().__new__(cls) 。哪些代码行有助于创建这个类 Singleton ?

    2 回复  |  直到 6 年前
        1
  •  4
  •   VoNWooDSoN    6 年前

    好吧,详细回顾一下:

    class Singleton: 隐式继承自 Object 因为在巨蟒中 一切 是一个对象。

    instance = None 仅在模块加载时读取,并设置类级变量 instance 成为 None 一次 但是它可以被类的单个实例重写 Singleton .

    def __new__(cls):
        if cls.instance is None:
            cls.instance = super().__new__(cls)
        return cls.instance
    

    (首先,我认为他们把“cls”放在里面很奇怪,我知道他们为什么这么做,因为这是指课堂 总体的 而不是该类的特定实例。但是,这会让人困惑,所以有些人不知道自己在看什么。不管怎样…)

    __new__ 是以前调用的魔力函数 __init__ 这大致类似于为类的新实例分配空间。在这里, cls.instance 设置为 没有 在模块加载时,因此每次 单子 正在创建此测试已完成。自从 cls.实例 第一次设置为 单子 是创建的, super().__new__(cls) 也是 只呼叫过一次 . 超级级的 单子 对象 . 所以 super()新建(cls) 正是您希望它适用于您创建的任何其他类。
    如果,您正在创建的第二个(,或第三个/第四个/第五个…)实例 单子 那么这个 super()新建(cls) 不会被调用。而是类级变量 实例 返回,意思是 没有新的实例 单子 可以创建 .

    当您打印 单子 然后你就可以看到 0x10dbc0f60 两个“实例”都相同,因为 cls.实例 返回时间: _新建__ 时间,你可以把它看作是内存分配时间 _初始化__ 被调用。

    这是执行单例模式的一个好方法,因为为了创建单例类,现在您所要做的就是继承自 单子 重吊已经完成了。你去用吧 _初始化__ 就像你平时那样,别担心。每次你去创建这个类的“新”实例时,你都会得到相同的实例。完全在幕后。

    这是相当先进的东西,但看它有多简单。巨蟒是最好的!

        2
  •  6
  •   Dragonthoughts    6 年前

    建造师说,

    If there is no instance recorded, 
       create an instance and record it
    return the recorded instance
    

    对于大多数语言,这是一个标准的单例设计模式,以确保只创建类的一个实例。