在模块之间共享单例

dom*_*om0 10 python singleton python-3.x

给定两个模块,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
Run Code Online (Sandbox Code Playgroud)

和x,分别为:

import main

print(id(main.uvw))
print(main.uvw.x)
Run Code Online (Sandbox Code Playgroud)

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

$ python main.py
140592861777168
20
140592861207504
10
Run Code Online (Sandbox Code Playgroud)

有什么方法可以确保uvw两个地方都是同一个物体吗?

Eri*_*ric 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
Run Code Online (Sandbox Code Playgroud)

a.py:

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)
Run Code Online (Sandbox Code Playgroud)

b.py:

from singleton import Singleton
uvw = Singleton()
print(id(uvw))
uvw.x += 10
print(uvw.x)
Run Code Online (Sandbox Code Playgroud)

main.py

import a
import b
Run Code Online (Sandbox Code Playgroud)


joe*_*eln 6

Python按名称加载每个模块一次(除非reload(module)被调用).如果您运行main.py,模块是__main__(尝试打印uvw.__class__.__module__).当x进口main,被称为模块main被加载首次.

如果你uvw在第三个模块中定义,或者x- 只要它以相同的方式导入__main__x- 它将是同一个对象.