2017-09-04 58 views
0

工作,我發現我的代碼中一個奇怪的循環引用,這裏是最小碼:爲什麼這個圓形進口* *將在Python

ph 
|-- mod 
| |-- __init__.py 
| |-- pkg.py # import mod.sub_mod.sub_pkg 
| `-- sub_mod 
|  |-- __init__.py 
|  `-- sub_pkg.py # from mod import pkg 
`-- main.py 
mod

,只有pkg.pysub_pkg.py有文件內容。

main.py

import mod.pkg 

將導致ImportError,但

import mod.sub_mod.sub_pkg 

效果很好。

當我試圖找到這個最小可重現的例子時,我發現在python 3中,兩個導入都可以工作。 我還發現這個網頁:https://gist.github.com/datagrok/40bf84d5870c41a77dc6但我仍然不知道爲什麼。

+1

也許參見[「導入Python模塊」在effbot.org上](http://effbot.org/zone/import-confusion.htm#circular-imports) – poke

回答

1

如果您以import mod.pkg開始循環導入,則首先啓動mod/pkg.py,並嘗試到import mod.sub_mod.sub_pkgmod/sub_mod/sub_pkg.py啓動,並嘗試運行from mod import pkg,但mod.pkg模塊已被初始化。

Python跳到試圖從mod模塊對象檢索pkg屬性。但是,該屬性在mod.pkg模塊完成初始化之前未設置,因此from mod import pkg失敗。


如果用import mod.sub_mod.sub_pkg先啓動導入圓形,然後mod/sub_mod/sub_pkg.py啓動,並嘗試運行from mod import pkgmod/pkg.py開始,並嘗試import mod.sub_mod.sub_pkgmod.sub_mod.sub_pkg模塊已經初始化,但這次Python不會嘗試訪問屬性。

from mod import pkg需要從mod檢索pkg屬性,因爲它需要該屬性的值綁定到名稱pkg在當地的命名空間。但是,import mod.sub_mod.sub_pkg僅綁定本地名稱空間中的mod名稱。 Python將mod名稱綁定到mod.pkg的模塊名稱空間中的mod模塊並繼續。


在Python 3,在第一種情況下,有當from mod import pkg未能找到modpkg屬性的回退。 Python會檢查sys.modules字典,查找'mod.pkg'的條目,找到一個,並將其找到的模塊綁定到名稱pkg