模組a中import b,而在模組b中import a。這時會怎麼樣呢?這個在python列表中由robertchen給出了詳細解釋,抄錄如下:
[a.py]為什麼執行a的時候不能載入d呢?from b import d
class c:pass
[b.py]
from a import c
class d:pass
如果將a.py改為:import b就可以了。
這是怎麼回事呢?
robertchen:這跟python內部import的機制是有關的,具體到from b import d,python內部會分成幾個步驟:
在sys.modules中查詢符號"b"
果符號b存在,則獲得符號b對應的module物件。
從的__dict__中獲得符號"d"對應的物件,如果"d"不存在,則丟擲異常
如果符號b不存在,則建立乙個新的module物件,注意,這時,module物件的__dict__為空。
執行b.py中的表示式,填充的__dict__ 。
從的__dict__中獲得"d"對應的物件,如果"d"不存在,則丟擲異常。
所以,這個例子的執行順序如下:
1、執行a.py中的from b import d
由於是執行的python a.py,所以在sys.modules中並沒有存在,首先為b.py建立乙個module物件(),注意,這時建立的這個module物件是空的,裡邊啥也沒有,在python內部建立了這個module物件之後,就會解析執行b.py,其目的是填充這個dict。
2、執行b.py中的from a import c
在執行b.py的過程中,會碰到這一句,首先檢查sys.modules這個module快取中是否已經存在了,由於這時快取還沒有快取,所以類似的,python內部會為a.py建立乙個module物件(),然後,同樣地,執行a.py中的語句。
3、再次執行a.py中的from b import d
這時,由於在第1步時,建立的物件已經快取在了sys.modules中,所以直接就得到了,但是,注意,從整個過程來看,我們知道,這時還是乙個空的物件,裡面啥也沒有,所以從這個module中獲得符號"d"的操作就會丟擲異常。如果這裡只是importb,由於"b"這個符號在sys.modules中已經存在,所以是不會丟擲異常的。
上面的解釋已經由zoom.quiet收錄在啄木鳥了,裡面有圖,可以參考一下:
Python學習之路 模組詳解及import本質上
1.定義 模組 用來從邏輯上組織python 變數,函式,類,邏輯 實現乙個功能 本質就是.py結尾的python檔案。檔名 test.py,對應的模組名 test 包 用來從邏輯上組織模組的,本質是乙個資料夾或者目錄 必須帶乙個 init py檔案 2.匯入方法 import module nam...
Python包 模組和包匯入詳解(import)
1.模組 module 1.1 模組定義 通常模組為乙個.py檔案,其他可作為module的檔案型別還有 pyo pyc pyd so dll module 可看作乙個工具類,可共用或者隱藏 細節,將相關 放置在乙個module以便讓 更好用 易懂,讓coder重點放在高層邏輯上。module能定義...
Python與C C 模組相互呼叫
開源中國推出 paas osc 演示和執行平台 python呼叫c動態鏈結庫 python呼叫c庫很簡單,不經過任何封裝打包成so,再使用python的ctypes呼叫即可。原始碼列印?include extern c g test.cpp fpic shared o libtest.so 原始碼列...