2013-05-10 26 views
2

簡而言之:在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大號建議是一樣的東西工作正常(只要我不在多線程上調用導入)。任何人都有更好的?

+0

'aa.py將獲得2套全球variables'的。你能舉一個這樣的例子嗎?從我看到Python讀取aa.py兩次,因此執行兩次print語句,b.py仍然只有一個全局變量'aa'。 '__name__'只是在導入時顯示模塊名稱。取決於你如何執行,它可能是'__main__'。 – 2013-05-10 06:08:51

+0

也許使用def setV(x):global v,v = x 和getV():global v,return v。我很肯定它不會工作,因爲模塊導入了兩次 – 2013-05-10 07:10:29

回答

0

的問題是,你正在做可從您的路徑中兩個不同的條目模塊。

這是不該發生的事情,你應該讓整個項目目錄位於路徑中,並且所有模塊導入完成,而不管項目中的位置是否使用導入的完整路徑,所以,而不是您的示例,它應該是:

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

而你將永遠需要使用上b.py第一線的進口,如:

from a import aa 
相關問題