2

简而言之:在 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__

它似乎工作正常(只要我不在多个线程上调用导入)。有人有更好的吗?

4

2 回答 2

2

这是一个丑陋的解决方法,但您可以使用 os.environ[] 来设置环境变量。我不太喜欢它,因为它会污染环境变量。

以下是如何设置这些: http ://code.activestate.com/recipes/159462-how-to-set-environment-variables/

祝你好运,盖伊

于 2013-05-10T07:09:22.763 回答
0

The problem is that you're making the module available from two different entries in your path.

That's something that shouldn't happen, you should have your entire project dir in the path, and all module imports done regardless of location inside the project use the full path for importing, so, instead of your example, it should be:

export PYTHONPATH=/test
python /test/b/b.py

And you'll always need to use the imports like on the first line of b.py:

from a import aa
于 2015-12-23T15:04:04.793 回答