亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python之import機制詳解

系統 2038 0

本文詳述了Python的import機制,對于理解Python的運行機制很有幫助!

1.標準import:

Python中所有加載到內存的模塊都放在 sys.modules 。當 import 一個模塊時首先會在這個列表中查找是否已經加載了此模塊,如果加載了則只是將模塊的名字加入到正在調用 import 的模塊的 Local 名字空間中。如果沒有加載則從 sys.path 目錄中按照模塊名稱查找模塊文件,模塊可以是py、pyc、pyd,找到后將模塊載入內存,并加到 sys.modules 中,并將名稱導入到當前的 Local 名字空間。

一個模塊不會重復載入。多個不同的模塊都可以用 import 引入同一個模塊到自己的 Local 名字空間,其實背后的 PyModuleObject 對象只有一個。這里說一個容易忽略的問題:import 只能導入模塊,不能導入模塊中的對象(類、函數、變量等)。例如:模塊 A(A.py)中有個函數 getName,另一個模塊不能通過 import A.getName 將 getName導入到本模塊,只能用 from A import getName。

2.嵌套import:

1)順序嵌套

例如:本模塊導入 A 模塊(import A),A 中又 import B,B 模塊又可以 import 其他模塊……
這中嵌套比較容易理解,需要注意的一點就是各個模塊的 Local 名字空間是獨立的。對于上面的例子,本模塊 import A 之后本模塊只能訪問模塊 A,不能訪問模塊 B 及其他模塊。雖然模塊 B 已經加載到內存了,如果訪問還要再明確的在本模塊中 import B。

2)循環嵌套

例如:

文件[A.py]

            
from B import D
class C:pass

          

文件[ B.py ]

            
from A import C
class D:pass

          

為什么執行 A 的時候不能加載 D 呢?
如果將 A.py 改為:import B 就可以了。
這是怎么回事呢?

RobertChen:這跟Python內部 import 的機制是有關的,具體到 from B import D,Python 內部會分成幾個步驟:
(1)在 sys.modules 中查找符號 “B”
(2)如果符號 B 存在,則獲得符號 B 對應的 module 對象。
? 從 的 __dict__ 中獲得符號 “D” 對應的對象,如果 “D” 不存在,則拋出異常。
(3)如果符號 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"的操作就會拋出異常。 如果這里只是import B,由于"B"這個符號在sys.modules中已經存在,所以是不會拋出異常的。

ZQ:圖解如下:

python之import機制詳解_第1張圖片

3. 包 import

只要一個文件夾下面有個 __init__.py 文件,那么這個文件夾就可以看做是一個包。包導入的過程和模塊的基本一致,只是導入包的時候會執行此包目錄下的 __init__.py 而不是模塊里面的語句了。另外,如果只是單純的導入包,而包的 __init__.py 中又沒有明確的其他初始化操作,那么此包下面的模塊是不會自動導入的。
?例如:
? 有下面的包結構:
? PA
? |---- __init__.py
? |---- wave.py
? |---- PB1
??????? |---- __init__.py
??????? |---- pb1_m.py
? |---- PB2
??????? |---- __init__.py
??????? |---- pb2_m.py
有如下程序:

            
import sys
import PA.wave              #1
import PA.PB1                #2
import PA.PB1.pb1_m as m1    #3
import PA.PB2.pb2_m          #4
PA.wave.getName()           #5
m1.getName()                #6
PA.PB.pb2_m.getName()       #7

          

1) 當執行 #1 后,sys.modules 會同時存在 PA、PA.wave 兩個模塊,此時可以調用 PA.wave 的任何類或函數了。但不能調用 PA.PB1(2) 下的任何模塊。當前 Local 中有了 PA 名字。

2) 當執行 #2 后,只是將 PA.PB1 載入內存,sys.modules 中會有 PA、 PA.wave、PA.PB1 三個模塊,但是 PA.PB1 下的任何模塊都沒有自動載入內存,此時如果直接執行 PA.PB1.pb1_m.getName() 則會出錯,因為 PA.PB1 中并沒有 pb1_m 。當前 Local 中還是只有 PA 名字,并沒有 PA.PB1 名 字。

3) 當執行 #3 后,會將 PA.PB1 下的 pb1_m 載入內存,sys.modules 中會有 PA、PA.wave、PA.PB1、PA.PB1.pb1_m 四個模塊,此時可以執行 PA.PB1.pb1_m.getName() 了。由于使用了 as,當前 Local中除了 PA 名字,另外添加了 m1 作為 PA.PB1.pb1_m 的別名。

4) 當執行 #4 后,會將 PA.PB2、PA.PB2.pb2_m 載入內存,sys.modules 中會有 PA、PA.wave、PA.PB1、PA.PB1.pb1_m、PA.PB2、PA.PB2.pb2_m 六個模塊。當前 Local 中還是只有 PA、m1。
下面的 #5,#6,#7 都是可以正確運行的。

注意的是: 如果 PA.PB2.pb2_m 想導入 PA.PB1.pb1_m、PA.wave 是可以直接成功的。最好是采用明確的導入路徑,對于 ./.. 相對導入路徑還是不推薦用。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩欧美中文字幕一区 | 久久99热这里只有精品国产 | 香蕉视频在线免费看 | 亚洲 激情 | 手机看片福利盒子久久青 | 国产精品一区不卡 | 特级做人爱c级特级aav毛片 | 99久久精品一区二区三区 | 欧美亚洲第一区 | 精品一区二区三区视频在线观看 | 久久91亚洲精品久久91综合 | 日本色图在线 | 日日夜夜免费精品 | 成人国产精品视频 | 中文字幕久久综合伊人 | 国产欧美日韩在线播放 | 久久久麻豆 | 欧美日韩激情在线 | 中文字幕亚洲一区二区v@在线 | 国产亚洲精品美女久久久久 | 狠狠色很很在鲁视频 | 久久精品一区二区三区不卡牛牛 | www.一级毛片| 久久免 | 成年女人18级毛片毛片 | 99热久久这里只有精品7 | 婷婷在线成人免费观看搜索 | 国产精品免费一级在线观看 | 青青青国产手机免费视频 | 亚洲va在线va天堂成人 | 日本在线不卡免费 | 色综合五月激情综合色一区 | 激情综合网五月 | 成人禁在线观看午夜亚洲 | 亚洲精品免费在线 | 天天夜夜狠狠 | 啪啪免费网站入口链接 | 日韩一区三区 | 亚洲国产97在线精品一区 | 亚洲综合图片小说区热久久 | 国内免费一区二区三区视频 |