11

给定两个模块,main 和 x,其内容如下:

主要的:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        cls._instance.x = 10
        return cls._instance
uvw = Singleton()

if __name__ == "__main__":
    print(id(uvw))
    uvw.x += 10
    print(uvw.x)
    import x

和 x 分别为:

import main

print(id(main.uvw))
print(main.uvw.x)

我现在希望执行 main 会在两个实例中产生相同的 ID 和值 20,但我得到的是:

$ python main.py
140592861777168
20
140592861207504
10

有什么办法可以确保uvw两个地方都是同一个对象吗?

4

3 回答 3

8

我认为问题在于您的Singleton类正在以某种方式重新加载,因此_instance在第二个模块中丢失了它的字段。


我认为这会起作用:

singleton.py

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        cls._instance.x = 10
        return cls._instance

a.py

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)

b.py

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)

main.py

import a
import b
于 2012-11-11T12:16:00.927 回答
7

Python 按名称加载每个模块一次(除非reload(module)被调用)。如果你运行main.py,模块是__main__(尝试打印uvw.__class__.__module__)。x导入时main,调用的模块main是第一次加载。

如果您uvw在第三个模块中定义,或者在x-- 只要它以相同的方式导入到__main__并且x-- 它将是同一个对象。

于 2012-11-11T12:20:35.053 回答
1

我发现问题是main从命令行执行时加载了两次,一次是 as __main__,第二次是由 x as 导入时main

我发现了一个非常邪恶的黑客来规避第二次加载:

sys.modules["main"] = sys.modules["__main__"]

在我的情况下,将主模块和单例类分开是不利的。

于 2012-11-11T12:16:56.583 回答