如何在Python中检测或阻止相同模块的多个实例?

时间:2013-05-10 04:41:56

标签: python import module instance

简而言之:在Python中,创建同一模块的多个实例太容易了, 每个实例都有自己的全局变量集。

我需要在模块中添加一个检查来检测这种多实例化 并提出例外。

我的问题与此问题相同: Module imported 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
...

因此,很明显有2个变量test_var的实例。如果我将尝试在此模块中实现单例,则此单例将有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__

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

2 个答案:

答案 0 :(得分:2)

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

以下是设置这些内容的方法: http://code.activestate.com/recipes/159462-how-to-set-environment-variables/

祝你好运, 盖

答案 1 :(得分:0)

问题在于,您可以从路径中的两个不同条目中获取模块。

这不应该发生的事情,你应该在路径中拥有整个项目目录,并且无论项目内部的位置如何,所有模块导入都使用导入的完整路径,因此,而不是你的例子,它应该是:

SysUtils

你总是需要使用b.py第一行的导入:

$insrtMar = "INSERT INTO parishioner (firstname,middlename,lastname,sex,household_head,household,civil_status,birthdate,birthplace,citizenship,occupation,sponsors_female,sponsors_male,email,date_of_seminar) VALUES ('$firstname1','$middlename1','$lastname1','$sex1','$household_head1','$household1','$civil_status1','$bday1','$bplace1','$citizenship1','$occupation1','$sponsors_female1','$sponsors_male1','$email1','$date_of_seminar1'),('$firstname2','$middlename2','$lastname2','$sex2','$household_head2','$household2','$civil_status2','$bday2','$bplace2','$citizenship2','$occupation2','$sponsors_female2','$sponsors_male2','$email2','$date_of_seminar2')";