有以下 a.py 和 b.py 兩個模組:
a.py
print(1)
aaa = 111
print(2)
def a():
print(3)
from b import b
print(4)
b()print(5)
aa = a()
print(6)
b.py
from a import aaa
def b():
print(aaa)
問:匯入 import a 和 直接執行 python3 a.py,在結果上會有什麼不同?原因是什麼?
當作模組匯入 import a:1 2 5 3 4 111 6
直接執行 a.py:1 2 5 3 1 2 5 3 然後丟擲 importerror: cannot import name 'b' 異常
跟 python 的匯入和執行機制有關。
當 import 乙個模組時,python 首先檢查該模組是否已經被 import 過:
所以如果 a 模組中 import 了 b 模組,並且 b 模組裡又 import 了 a 模組,那麼在呼叫 import a 時執行順序就會變成這樣:
>>> import a
開始執行模組 a 的**
當 a 執行到 import b 的地方,停止執行 a 模組後面的**,轉而開始執行 b 模組的**
當 b 模組從頭執行到 import a 的地方時,python 此時並不會回過頭去接著執行 a 剩餘的**,而是將 a 模組在中斷前已經初始化的屬性全載入到 b 模組中
b 模組繼續執行後面的**,執行完成後再返回 a 模組執行剩餘**
理解了上面的 import 執行機制和過程後,再來分析這個題目的實際執行結果:
當作模組匯入:python -m a.py or >>> import a
a 模組首次被匯入,從頭開始執行 a.py 的**
a.py 執行到第 2 行時,變數 aaa 被宣告
a.py 執行到第 5 行時,方法 a() 被宣告
a.py 執行到第 12 行時,變數 aa 被宣告,方法 a() 被執行
a.py 方法 a() 執行到第 7 行時,from b import b 匯入了 b 模組
b 模組首次被匯入,a.py 中斷執行,從頭開始執行 b.py 的**
b.py 執行到第 1 行時,from a import aaa 匯入了 a 模組
a 模組已經被匯入過,並且 a 模組首次匯入時變數 aaa 已經被宣告,所以 aaa 可以被成功匯入到 b 模組中
b.py 繼續執行到第 3 行時,方法 b() 被宣告
b 模組執行結束,此時 b 模組的方法 b() 已經被宣告,所以 b() 被匯入到 a 模組中
a 模組繼續執行方法 a() 剩下的**
a.py 方法 a() 執行到第 9 行時,呼叫了從 b 模組匯入進來的方法 b()
b 模組的方法 b() 被執行
b.py 方法 b() 執行到第 4 行時,列印了從 a 模組匯入的變數 aaa
b.py 方法 b() 執行完畢,跳回 a.py 方法 a()
a.py 方法 a() 執行完畢,跳出方法 a()
a.py 繼續執行第 13 行的**
a 模組執行完畢,匯入結束
按照以上執行順序,會依次列印 1 2 5 3 4 111 6
直接執行:python a.py
a.py 正常執行
a.py 方法 a() 執行到第 7 行時,from b import b 匯入了 b 模組
b 模組首次被匯入,a.py 中斷執行,從頭開始執行 b.py 的**
b.py 執行到第 1 行時,from a import aaa 匯入了 a 模組
a 模組首次被匯入,b.py 中斷執行,從頭開始執行 a.py 的**
( 劃重點:注意這裡 a 模組是首次被匯入!雖然程式一開始就執行了 a.py,但是並沒有 import a,所以這裡會被當作首次匯入對待,a.py 的**會從頭再執行一次 )a.py 再次被執行到方法 a() 的第 7 行時,from b import b 匯入了 b 模組
b 模組已經被匯入過,不會再去執行 b.py,但 b 模組首次匯入時還沒有執行到第 3 行就中斷了,導致方法 b() 未被宣告,所以拋錯「importerror: cannot import name 'b'」
( 劃重點:b 模組首次匯入時,執行到第 1 行 from a import aaa 便中斷了,轉而去執行 a.py,此時方法 b() 還是未被宣告的;b 模組再次被匯入時,因為之前已經匯入過,所以並不會實際執行,方法 b() 始終得不到宣告,而「from b import b 」又想從 b 模組匯入 b(),顯然就會報錯 )
按照以上執行順序,得到以下輸出:1 2 5 3 1 2 5 3 然後丟擲 importerror: cannot import name 'b' 異常
python import匯入模組
常規匯入 regular imports 使用from語句匯入 相對匯入 relative imports 可選匯入 optional imports 本地匯入 local imports 常規匯入 常規匯入應該是最常使用的匯入方式,大概是這樣的 import sys你只需要使用import一詞,然...
python import匯入現有模組
主要分三種情況 1 主程式與模組程式在同一目錄下 如下面程式結構 src mod1.py test1.py 若在程式test1.py中匯入模組mod1,則直接使用importmod1或from mod1 import 2 主程式所在目錄是模組所在目錄的父 或祖輩 目錄 如下面程式結構 src mod...
Python import 匯入功能詳解
1 import 匯入模組 包 預設從執行的檔案的資料夾下尋找 2 當檔名跟系統內建的模組重名,import還是匯入系統內建的模組 3 import xx檔案,會把xx檔案執行一遍,再把檔案引入。4 可通過 隔開檔案,以通過一行匯入多個檔案。跟通過多行匯入效果一樣 例如 import time,os...