Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Singleton的Python实现_Python_Singleton_Decorator - Fatal编程技术网

Singleton的Python实现

Singleton的Python实现,python,singleton,decorator,Python,Singleton,Decorator,首先是代码: def singleton(cls): instances = {} def get_instance(): if cls not in instances: instances[cls] = cls() return instances[cls] return get_instance @singleton class A: #... 好的,我看到上面的代码是Singleton的一个实现

首先是代码:

def singleton(cls):
    instances = {}
    def get_instance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return get_instance

@singleton
class A:
    #...
好的,我看到上面的代码是Singleton的一个实现

我不明白为什么singleton函数返回一个函数,而a是一个类。
它是如何工作的?

当你在装饰后调用
MyClass()
时,你是对的——你实际上不是在调用一个类,而是在调用一个函数

如果cls不在实例中,该函数将调用类
,并将其缓存,然后返回缓存的实例


换句话说,
MyClass()
没有理由直接调用该类——只要它返回一个类的实例,它就会正常工作。

A最终不是一个类。类A被创建,但随后被singleton返回的函数替换。所以最后,A是一个函数

但是,由于您调用一个类来创建一个对象,它最终的工作方式基本相同。但iInstance不起作用


另外,你可能不应该用单身汉。在python中,它几乎总是错误的选择。

@Jim,对不起,我会更加小心。为什么我不应该使用singleton呢?如果我使用new?@Alcott在站点上搜索pythonsingleton,或者阅读“相关”列表中的问题,会怎么样。它已经被处理过很多次了。@Alcott A singleton与全局变量完全相同。如果你真的需要一个,只需将你的单例类实例化一次,变成一个全局变量,而不是搞这种愚蠢的缓存技术,然后用
MySingletonClass()
替换everywhere
MySingletonInstance
。单例通常是一个坏主意,原因与全局通常是一个坏主意相同,如果您的代码看起来像是在实例化一个新实例,而不是引用一个全局变量,那么就更难找出代码中不直接通信的部分之间的秘密通信通道。@Alcott,如果你的单例对象有状态,那么你已经创建了一个全局变量。如果您的单例对象没有状态,那么您已经创建了一个模块。无论哪种方式,使用单身都没有任何帮助。有关如何正确避免全球状态的演示,请参阅。@Winston,谢谢你的链接,但我无法观看,因为我在中国,:PYep,它工作正常。它保存一个实例,并在您调用
MyClass()
时返回它。True,但大多数情况下这并不重要——您通常不需要在Python中检查类型,只需使用它,如果它不支持正确的接口,它将给出一个错误。@agf,True。虽然还有一些东西像泡菜一样坏了。用函数替换类就足够了。@WinstonEwert我同意,如果你真的需要一个单例,还有更好的实现(这里有很多Python单例问题)。