简而言之:在 Python 中创建同一个模块的多个实例太容易了,每个实例都有自己的一组全局变量。
我需要在模块中添加一个检查来检测这样的多个实例化并引发异常。
我的问题和这个一样: Module import multiple times
这是重现问题的最小目录结构:
/test/a/__init__.py
/test/a/aa.py:
print "aa: __name__: ", __name__
/test/b/b.py:
from a import aa
import aa
然后
export PYTHONPATH=/test:/test/a
python /test/b/b.py
印刷:
aa: __name__: a.aa
aa: __name__: aa
因此,模块 aa.py 以不同的名称导入了两次。
不用说,模块 aa.py 将获得 2 组全局变量,这会破坏该模块内部的所有逻辑。
当然,在上面的简单示例中,很容易通过肉眼检测错误,但在具有多个子目录的复杂项目中,这些错误会定期弹出。
所以,我需要一些真正的全局变量或进程范围的存储或类似的东西。任何想法?
编辑:Bibhas 要求提供同一全局变量的多个实例的示例。这里是:
/test/a/__init__.py
/test/a/aa.py:
print "aa: __name__: ", __name__
import thread
import time
test_var = __name__
def test():
for i in range(0,5):
print "aa thread: test_var: ", test_var
time.sleep(1)
thread.start_new_thread( test, () )
/test/b/b.py:
print "b: __name__: ", __name__
from a import aa
import aa
import time
time.sleep(10)
现在运行
export PYTHONPATH=/test:/test/a
python /test/b/b.py
印刷:
aa: __name__: a.aa
aa: __name__: aa
aa thread: test_var: aa
aa thread: test_var: a.aa
aa thread: test_var: aa
aa thread: test_var: a.aa
...
因此,很明显变量 test_var 有 2 个实例。如果我尝试在这个模块中实现一个单例,那么这个单例会有 2 个实例,等等。
Edit2:所以,Guy L 建议的解决方案类似于:
/test/a/aa.py:
import os
if "aa.py" in os.environ:
raise Exception("Duplicate instantiation of aa.py")
os.environ["aa.py"] = __name__
它似乎工作正常(只要我不在多个线程上调用导入)。有人有更好的吗?