簡而言之:在Python中,創建同一個模塊的多個實例太容易了,每個實例都有自己的一組全局變量。如何在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
...
所以,很顯然,有可變test_var的兩個實例。如果我將盡力實現這個模塊中的單,就會有這個單身的2個實例等
EDIT2:到
/test/a/aa.py:
import os
if "aa.py" in os.environ:
raise Exception("Duplicate instantiation of aa.py")
os.environ["aa.py"] = __name__
看來:那麼,解決方案由Guy大號建議是一樣的東西工作正常(只要我不在多線程上調用導入)。任何人都有更好的?
'aa.py將獲得2套全球variables'的。你能舉一個這樣的例子嗎?從我看到Python讀取aa.py兩次,因此執行兩次print語句,b.py仍然只有一個全局變量'aa'。 '__name__'只是在導入時顯示模塊名稱。取決於你如何執行,它可能是'__main__'。 – 2013-05-10 06:08:51
也許使用def setV(x):global v,v = x 和getV():global v,return v。我很肯定它不會工作,因爲模塊導入了兩次 – 2013-05-10 07:10:29