【问题标题】:Python Singletons syntax and why its looks like that?Python Singletons 语法以及为什么它看起来像这样?
【发布时间】:2011-07-09 11:38:09
【问题描述】:

我的第一个问题:

我已经在互联网上搜索过,也在这里阅读了几个问题和答案,最后找到了为我的 python 代码编写单例类的方法。 我还阅读了有关 new() 函数和其他一些内容的 python 文档,但仍然对所有 new(cls, *args , **kw) 东西等等!

例如我写了这样的测试代码:

class Singleton(object):

    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls):
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class printer(Singleton):

    def __init__(self):

        print "I am a new Object, and will remain until the end of time!"

if __name__ == '__main__':
    printer()

结果是文本“我是一个新的对象,将一直存在到时间的尽头!” 但是这是如何工作的,我的意思是,我不知道该怎么说,例如我真的很困惑:

vars(cls):在if '_inst' not in vars(cls)行中

vars(cls) 从哪里出来,我之前没有声明过! 有人可以为我在单例类中澄清这些事情以及关于最后一行的一些内容

if __name__ == '__main__':
    printer()

【问题讨论】:

  • 具有讽刺意味的是,这种对单例的尝试甚至都无法正常工作。有人无法满足于一个名字,现在您可以根据需要实例化任意多个...

标签: python syntax singleton new-operator main


【解决方案1】:

首先,这是错误的:

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls): # <-- this must of course also be "_instance"
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

一个显式的__new__方法可以像工厂模式一样使用,所以当你写printer()时,Python会首先调用__new__,传递类类型和构造函数参数(在这个例子中没有)。

'_instance' not in vars(cls) 只是意味着查找该类是否已经有一个名为“_instance”的属性(即单例)。如果没有,则创建一个。 vars(内置函数,回答您的问题)的技巧不是必需的,例如,也可以使用cls._instance 并捕获AttributeError

最后一件事:

if __name__ == '__main__':
    printer()

如果直接执行脚本(即如果__name__ == '__main__',而不是导入模块),这只会创建一个printer 实例(使用Singleton.__new__)。

【讨论】:

  • 感谢 AndiDog 的帮助。你能解释一下namemain的功能吗?这些是范围的种类还是它们是什么?我读过 main 是一个作用域,python 在其中保存从解释器运行或作为独立运行的每一段代码。
  • __name__ 是当前模块的名称。这个魔法变量通常在编写启动器时使用——如果你直接执行 Python 脚本,它将被 Python 解释器导入为__main__。例如,一些内置模块在直接执行时表现不同(例如 SimpleHTTPServer 运行 Web 服务器)。请注意,如果启动的模块稍后是通过其模块名称导入的,那么您有两个不同的模块,一个是__main__,一个是命名模块。这个can lead to problems
【解决方案2】:

您应该在 python 中将模块用作单例,因为它们的行为完全一样。

这是另一个问题:Is there a simple, elegant way to define singletons?

【讨论】:

  • 是的,但没有投票,因为它并没有真正回答问题(解释一下 codez)。
【解决方案3】:

您是否考虑过使用Borg,而不是使用单例?

这个想法是,因为 Python 将实例的所有状态存储在一个属性 (__dict__) 中,如果您只是将该属性重新分配给一个类属性,那么您可以根据需要多次实例化该类,但它们都会具有相同的状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 2011-04-29
    相关资源
    最近更新 更多