为什么在不同模块中会出现同一个单例的不同实例?
我有两个文件,它们都打印一个单例实例,但我却得到了两个不同的实例。
我使用的是来自 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>
有人能告诉我发生了什么吗?看起来是在模块层面上出了问题,导致了这种行为。
2 个回答
0
我不太明白你为什么需要单例模式,但看到你提到的那个“单例混合类”让我想起了一封老笑话链邮件,里面展示了程序员(退化)的不同阶段,以及各种“你好,世界”程序的例子。在那封邮件中,最低点是“企业级高级程序员”,他们为了写出“你好,世界”开发了一个客户端-服务器系统,使用了各种设计模式。
而在同一段文字中,最高点是“高手黑客”,他们只用一行代码就实现了“你好,世界”: echo Hello World!
所以,很可能你只需要一个类,而不是它的实例。这样它就会在所有方面表现得像一个单例。如果你想确保它不会被实例化,可以在new方法中抛出一个异常:
class SimpleSingleton(object):
@classmethod
def my_singleton_method(cls,):
pass
def __new__(cls):
raise TypeError("Cannot be instantiated")
4
你得到两个单例的原因是因为模块导入的方式。当你从命令行运行 test.py 时,它并不是以 test
的名字被识别,而是以 __main__
的名字。这个时候,sys.modules
中会添加一个名为 __main__
的条目,然后程序继续执行。当另一个文件(叫做 untitled)导入 test 时,sys.modules
会被检查,结果找不到名为 test
的模块,所以 test.py 又被执行了一次来导入它。这样一来,类 A
的定义就被执行了两次,导致产生了两个不同的类。因此,单例的实现认为这两个类是不同的,于是就产生了两个实例。