【问题标题】:Why do I get different instances of the same singleton in different modules?为什么我会在不同的模块中获得相同单例的不同实例?
【发布时间】:2011-01-28 01:59:41
【问题描述】:

我有 2 个打印单例实例的文件,但我得到了两个不同的实例。

我正在使用来自Gary Robinson 的单例代码。

这里是文件:

test.py

​​>
from singleton import Singleton
import untitled

class A(Singleton):
    def __init__(self):
        super(A, self).__init__()        

if __name__ == "__main__":
    a = A.getInstance()
    print a
    untitled.print_a()

untitled.py

​​>
def print_a():
    import test
    print test.A.getInstance()

...这是python test.py的输出

<__main__.A object at 0xaea270>
<test.A object at 0xaea3f0>

有人可以向我解释导致这种行为的原因(显然是在模块级别)吗?

【问题讨论】:

  • test2 模块中有什么? test2 是否从test.py 导入A

标签: python module singleton instances


【解决方案1】:

你得到两个单例的原因是模块被导入的方式。当你从命令行执行 test.py 时,它不是test,而是__main__。在名称__main__ 下向sys.modules 添加一个条目,然后继续执行。当无标题导入测试时,检查sys.modules,没有找到名为test的模块,所以再次执行test.py来导入它。结果,A 的类定义被执行了两次,产生了两个不同的类。因此,单例实现认为它们是不同的,并产生两个实例。

【讨论】:

  • 太棒了!谢谢内德!这正是我正在寻找的解释类型。我觉得有点令人惊讶。因此,另一个模块通过其模块名称 mm 导入 __main__ 模块的 Python 程序将被导入两次。因此,考虑到我正在做的事情,使用 classmethods 来创建 @jsbueno 建议的静态类是一个有争议的问题。
  • 保护自己免受此问题影响的最佳方法是在主文件之外保留尽可能多的代码,或者显式传递对象而不是重新导入主文件。
【解决方案2】:

我不知道你为什么需要单例,但是看看你指出的“单例混合”也让我想起了一个古老的笑话链电子邮件,显示了程序员 (d) 进化的各个阶段,带有 hello world 程序的各种示例。在那封邮件中,最低点是“企业级高级程序”,它开发了一个客户端服务器系统,实现了各种模式,以编写“Hello World”。

在同一篇文章中,最重要的是“黑客大师”,它用一行代码实现了 Hello world: 回声你好世界!

所以, 很可能您需要的只是一个使用该类而不是其实例的类。出于所有目的,它将表现得像一个单身人士。如果您想让 shure 不实例化,只需在 new 方法上引发异常:

class SimpleSingleton(object):
    @classmethod
    def my_singleton_method(cls,):
         pass
    def __new__(cls):
         raise TypeError("Cannot be instantiated")

【讨论】:

  • 当然,我可以使用静态类(我很欣赏这个建议),但这并不是真正的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
相关资源
最近更新 更多