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
?
答案 0 :(得分:6)
构造函数说,
java.time
对于大多数语言来说,这是一个标准的单例设计模式,以确保只创建一个类的实例。
答案 1 :(得分:4)
好的,在痛苦的细节中回顾一下:
class Singleton:
隐式继承自Object
,因为在python 中,所有都是对象。
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
在模块加载时设置为None
,因此每次创建新的Singleton
时都会完成此测试。由于cls.instance
是第一次创建Singleton
时设置的,super().__new__(cls)
也只是只调用一次。 Singleton
的超类是Object
。因此,super().__new__(cls)
的行为正是您所期望的任何其他课程的行为
如果您要创建Singleton
的第二个(或第三个/第四个/第五个......)实例,则不会调用此super().__new__(cls)
。而是返回类级变量instance
,这意味着不能创建Singleton
的新实例。
当您打印Singleton
的实例时,您可以看到0x10dbc0f60
的内存地址对于两个“实例”都相同,因为在cls.instance
时间返回__new__
,在调用__init__
之前,您可以将其视为内存分配时间。
这是执行Singleton模式的好方法,因为现在,要创建单例类,您所要做的就是从Singleton
继承,并且已经完成了繁重的工作。你继续像往常一样使用__init__
,不要担心。每次你去创建该类的“新”实例时,你都会得到相同的实例。完全在幕后。
这是非常先进的东西,但看起来有多简单。 python是最好的!