2012-09-19 30 views
2

我試圖加載代碼的模塊,然後重新加載相同的模塊,但不同的代碼編程的Python:無法加載在Python正確的模塊,而無需刪除PYC文件

import imp 

a = """ 
def test(): 
    print "Hello from a" 
""" 

b = """ 
def test(): 
    print "Hello from b" 
""" 


for code in [a, b]: 
    with open('user.py', 'wb') as f: 
     f.write(code) 
    mod = imp.load_source('user', 'user.py') 
    getattr(mod, "test")() 

預期輸出:

Hello from a 
Hello from b 

實際輸出:

Hello from a 
Hello from a 

顯然,我的它是如何工作的理解是不t正確,但我似乎無法弄清楚我的錯誤。

只有在編寫文件f中的代碼之前,我刪除了生成的.pyc文件,才能使其正常工作。有沒有更好的辦法?

+0

參見http://stackoverflow.com/questions/6477528/another-python-module-reload-question。 – nneonneo

回答

2

很可能不是因爲您的.pyc文件的時間戳(精確到秒)不會比您新編寫的.py文件的時間戳更早;因此imp將使用「當前」.pyc文件,除非您先刪除它。

另外,您可以嘗試等待兩秒鐘,然後重新加載模塊。

+2

請注意,對於FAT32文件系統,由於時間戳的粒度,您可能必須等待超過2秒。 – nneonneo

+1

好的,三秒鐘,然後:) –

3

如果您打算從字符串或文件中動態加載代碼,最好使用exec/execfile而不是importimport適用於靜態或很少更改的文件。

如果你還是想用imp.load_source,請注意以下幾點需要注意:

注意,如果正確匹配字節編譯的文件(後綴爲.pyc文件或.pyo)存在,它將被用來代替解析給定的源文件。

「正確匹配」表示編譯文件的版本與解釋器和時間戳匹配相匹配。正如Tim指出的那樣,如果連續快速寫入文件兩次,則時間戳可能不會更改,並且.pyc仍然會被視爲有效。

+0

注意:[This answer](http://stackoverflow.com/a/7548190/307705)解釋瞭如何使用'exec'在其自己的命名空間中加載模塊。你也可以將它加載到當前的命名空間中,但在大多數情況下我不會。 –

0

無論何時運行或導入python文件,模塊或包時,解釋器都會檢查是否存在與py文件版本匹配的pyc文件。如果是這樣,它將使用pyc文件,否則它將編譯py文件並覆蓋舊的pyc文件。如果pyc匹配py文件的版本是基於文件日期。既然你沒有保存你的文件(f),Python不會認識到它的改變。所以如果你想讓你的方法起作用,你需要在每個循環之後保存文件。