關於python中模塊的環狀引用(circular imports)

從stackoverflow上面copy過來的

1、

Imports are pretty straightforward really. Just remember the following:

'import' and 'from xxx import yyy' are executable statements. They execute when the running program reaches that line.

If a module is not in sys.modules, then an import creates the new module entry in sys.modules and then executes the code in the module. It does not return control to the calling module until the execution has completed.

If a module does exist in sys.modules then an import simply returns that module whether or not it has completed executing. That is the reason why cyclic imports may return modules which appear to be partly empty.

Finally, the executing script runs in a module named __main__, importing the script under its own name will create a new module unrelated to __main__.

Take that lot together and you shouldn't get any surprises when importing modules.


‘import’和‘from xxx import yyy' 是可執行語句,每當程序運行到他們所在的哪一行他們就執行,如果import的模塊在sys.modules中未找到,import語句就在sys.modules中會創建一個新的模塊,此時這個模塊就已經存在於sys.modules中了,但是他的__dict__還是空的,緊接着會執行這個模塊中的語句,以填充他的__dict__,直到這個模塊執行結束,纔會返回到剛纔的import語句繼續執行;如果import的模塊sys.modules中已經存在,那麼import語句將會直接返回這個模塊而不論他是否已經執行完畢,這就是爲什麼cyclic imports返回的模塊有時候會是空的


最後,執行腳本在命名爲__main__的模塊中運行,導入一個模塊將會在sys.modules中創建一個以自己名稱命名的和__main__模塊無關的模塊


2、

If you do import foo inside bar and import bar inside foo, it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.

The problem is when instead you do from foo import abc and from bar import xyz. Because now each module requires the other module to already be compiled (so that the name we are importing exists) before it can be compiled.

當你在bar模塊中執行import foo,同時在foo模塊中執行import bar,執行不會出現問題,直到兩個模塊中需要依賴彼此的程序執行時,兩個模塊纔會完全加載,而且擁有指向彼此的引用

當你在bar模塊中執行from foo import abc,同時在foo模塊中執行from bar import xyz,問題出現了。因爲這種情況下兩個模塊互相之間需要另一個模塊完全編譯完成,只有這樣,我們才能從另外一個模塊中找到我們需要import的名稱,但是很明顯這個時候我們的程序很難完全編譯完成,除非我們至少其中的一個from ... import ...出現在最後一行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章