【问题标题】:Python implementation of Singleton单例的 Python 实现
【发布时间】:2011-09-19 23:50:43
【问题描述】:

代码先行:

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的实现,我看到了this implementation in another post

我不明白为什么单例函数返回一个函数但 A 是一个类。 它是如何工作的?

【问题讨论】:

  • @Jim,对不起,我会更加小心。

标签: python singleton decorator


【解决方案1】:

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

但是由于你调用一个类来创建一个对象,它最终的工作方式几乎相同。但是 isinstance 不起作用。

附:你可能不应该使用单例。在 python 中,它几乎总是错误的选择。

【讨论】:

  • 为什么我不应该使用单例?如果我使用 new 实现单例设计模式会怎样?
  • @Alcott 在网站上搜索 Python Singleton,或阅读“相关”列表中的问题。已多次解决。
  • @Alcott 单例与全局变量相同。如果你真的需要一个,只需将你的单例类实例化一次到一个全局变量中,而不是搞乱这个愚蠢的缓存黑客,然后用MySingletonInstance 替换任何地方的MySingletonClass()。单例通常不是一个好主意,原因与全局通常是一个坏主意的原因相同,如果您的代码看起来就像是在实例化一个新实例而不是引用一个全局变量,那么它更难 找出不直接通信的代码部分之间的秘密通信通道。
  • @Alcott,如果你的单例对象有状态,那么你已经创建了一个全局变量。如果您的单例对象没有状态,那么您已经创建了一个模块。无论哪种方式,使用单例都没有任何帮助。有关如何正确避免全局状态的演示,请参阅 youtube.com/watch?v=-FRm3VPhseI
  • @Winston,感谢您的链接,但我无法观看,因为我在中国,:P
【解决方案2】:

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

该函数调用类if cls not in instances 并缓存它,然后返回缓存的实例。

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

【讨论】:

  • 是的,它工作正常。它保存一个实例并在您调用 MyClass() 时返回它。
  • 是的,但大多数时候这并不重要——你通常不需要在 Python 中检查类型,你只需使用它,如果不需要它会报错支持正确的接口。
  • @agf,真的。尽管其他一些东西像泡菜一样破碎。这足以让我对用函数替换类有点不安。
  • @WinstonEwert 我同意,如果你真的需要一个单例,有更好的实现(这里有很多 Python Singleton 问题)。
猜你喜欢
  • 2013-07-16
  • 2012-07-28
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多