给定两个模块,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
在两个地方都是同一个对象?
答案 0 :(得分:6)
我认为问题是你的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
答案 1 :(得分:6)
Python按名称加载每个模块一次(除非调用reload(module)
)。如果您运行main.py
,则模块为__main__
(尝试打印uvw.__class__.__module__
)。当x
导入main
时,第一次加载名为main
的模块。
如果您在第三个模块或uvw
中定义了x
,只要它以相同的方式导入__main__
和x
- 它将是同一个对象。
答案 2 :(得分:1)
我发现问题是main
在从命令行执行时加载了两次,一次加载__main__
,第二次加载x作为main
。
我找到了一个非常邪恶的黑客来规避第二次加载:
sys.modules["main"] = sys.modules["__main__"]
在我的情况下,分离主模块和单例类是不利的。