2014-12-07 73 views
1

我知道reload()功能可以在不影響from <module> import <name>" which were used before the重裝()',但我測試了一下,發現一個奇怪的現象:如何解釋使用「從X導入Y」導入一個函數Y在X文件中使用變量?

test1.py

message="before editing" 
def printer(): 
    print("reload",message) 

test1.py(改變):

message="after editing" 
def printer(): 
    print("reload",message) 

然後我用解釋器輸入:

from test1 import printer 
printer() 
import test1 
test1.printer() 

#change the test1.py 
reload(test1) 
test1.printer() 
printer() 

重裝後,結果是:

>>> test1.printer() 
('reload:', 'after editing') 
>>> printer() 
('reload:', 'after editing') 

那麼,爲什麼printer()看到改變?我認爲原因可能是變量綁定。

+0

我想知道爲什麼打印機()看到change.I將再次編輯該問題。謝謝 – ztelur 2014-12-07 03:14:34

回答

3

重新加載更新現有模塊。從一個模塊的功能包含對模塊全局的引用:

>>> printer.__globals__ is test1.__dict__ 
True 
>>> 'message' in printer.__globals__ 
True 
>>> printer.__globals__['message'] is test1.message 
True 

正是通過這一基準,像message全局都解決了。由於reload()函數更新了現有的模塊名稱空間,所以函數對象將使用新值。

reload()和從模塊導入的名稱(而不是對模塊本身的引用)的問題是這些引用不會更新。如果您已更改printer()函數本身的定義而不是message全局,則對該函數的導入引用不會發生更改。

reload() function documentation引用:

當一個模塊被重載,其字典(包含模塊的全局變量)被保留。名稱的重新定義將覆蓋舊的定義,所以這通常不是問題。

強調我的

+0

是重裝不能影響導入使用「from ** import」的函數,但函數包含對「 sys.modules「。重新加載後,sys.modules會更改,所以引用更改? – ztelur 2014-12-07 03:23:41

+0

@ztelur:no,'sys.modules ['test1']'*不會改變*。模塊對象就地更新。 – 2014-12-07 03:24:38

相關問題