在 Python 中,模塊(module)是一級(jí)命名空間對(duì)象。無論是通過 import 加載的標(biāo)準(zhǔn)庫(kù)模塊、第三方模塊,還是直接運(yùn)行的腳本本身,每個(gè)模塊都以對(duì)象形式存在于內(nèi)存中,并通過其 __dict__ 屬性統(tǒng)一管理所有模塊級(jí)名稱。
理解模塊的 __dict__,不僅是掌握模塊工作機(jī)制的關(guān)鍵,也是深入理解 Python 命名空間模型、導(dǎo)入機(jī)制以及運(yùn)行期動(dòng)態(tài)行為的重要基礎(chǔ)。
一、模塊對(duì)象與模塊命名空間
(1)模塊是運(yùn)行期對(duì)象,而非靜態(tài)概念
在 Python 中,模塊不是“代碼文件”的抽象概念,而是運(yùn)行期存在的實(shí)際對(duì)象。
print(type(math)) #每一個(gè)模塊對(duì)象都擁有一組標(biāo)準(zhǔn)屬性,例如:
? __name__:模塊名稱
? __file__:模塊源文件路徑
? __spec__:模塊的導(dǎo)入規(guī)范
? __loader__:模塊加載器
? __dict__:模塊命名空間
其中,__dict__ 是模塊命名空間的唯一物理載體,存儲(chǔ)了模塊中的所有名稱。
(2)模塊 __dict__ 的定義
模塊 __dict__ 表示模塊級(jí)的命名空間本身。模塊中通過賦值語句、函數(shù)定義、類定義、import 語句創(chuàng)建的所有名稱,最終都存儲(chǔ)在這個(gè)字典中。
示例:
pass加載后查看其命名空間:
print(demo.__dict__.keys())輸出:
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'x', 'f', 'C'])可以看到,模塊 __dict__ 既包含用戶定義的變量、函數(shù)、類,也包含系統(tǒng)自動(dòng)添加的元信息。
二、types 模塊與 ModuleType 的作用
為了準(zhǔn)確理解模塊 __dict__,需要明確模塊對(duì)象的具體類型。
(1)types 模塊的角色
標(biāo)準(zhǔn)庫(kù) 模塊提供了對(duì)解釋器內(nèi)部核心對(duì)象類型的標(biāo)準(zhǔn)化引用,如:
? FunctionType 函數(shù)類型
? MethodType 方法類型
? ModuleType 模塊類型
? GeneratorType 生成器類型
這些不是“新類型”,而是對(duì)既有內(nèi)置類型的正式命名,便于類型檢查和明確意圖。
(2)ModuleType 的本質(zhì)
types.ModuleType 表示模塊對(duì)象的類型:
print(type(math) is types.ModuleType) # True所有通過 import 得到的模塊對(duì)象,本質(zhì)上都是 ModuleType 的實(shí)例。
(3)ModuleType 的構(gòu)造語義
types.ModuleType(name, doc=None)參數(shù)含義:
? name:模塊名(對(duì)應(yīng) __name__)
? doc: 模塊文檔字符串(對(duì)應(yīng) __doc__)
示例:
print(m.__dict__) # {}(4)ModuleType 創(chuàng)建的是真實(shí)模塊對(duì)象
需要明確的一點(diǎn)是,types.ModuleType 創(chuàng)建的并不是“偽模塊”,而是真正的模塊對(duì)象。區(qū)別僅在于:
特性
import 創(chuàng)建的模塊
ModuleType 創(chuàng)建的模塊
代碼執(zhí)行
自動(dòng)執(zhí)行模塊代碼
不自動(dòng)執(zhí)行代碼
__dict__ 填充
自動(dòng)填充
初始為空字典
系統(tǒng)屬性
自動(dòng)設(shè)置 __spec__、__loader__
需手動(dòng)設(shè)置
注冊(cè)到 sys.modules
自動(dòng)注冊(cè)
不自動(dòng)注冊(cè)
在對(duì)象模型層面,它們完全一致:
print(type(m1) is type(m2)) # True(5)使用 ModuleType 的意義
使用 ModuleType 的目的在于:隔離模塊對(duì)象結(jié)構(gòu)本身與 import 機(jī)制的副作用。
示例:
print(m.__dict__) # {'x': 42, 'hello': at ...>}這清晰地體現(xiàn)了:
? 模塊屬性 ≡ 模塊 .__dict__ 中的鍵值對(duì)
? 模塊命名空間完全由模塊 __dict__ 管理
三、模塊 __dict__ 的生命周期
模塊 __dict__ 的生命周期與模塊對(duì)象本身嚴(yán)格一致。
(1)創(chuàng)建階段
執(zhí)行順序?yàn)椋?/p>
1、創(chuàng)建模塊對(duì)象:實(shí)例化 ModuleType
2、初始化空 __dict__:創(chuàng)建空字典作為命名空間
3、執(zhí)行模塊代碼:逐條執(zhí)行語句,將結(jié)果寫入 __dict__。
exec(open('demo.py').read(), demo.__dict__) # 導(dǎo)入過程的“概念性等價(jià)描述”(2)運(yùn)行階段:動(dòng)態(tài)可變
模塊 __dict__ 是一個(gè)完全可寫的普通字典,可在運(yùn)行時(shí)動(dòng)態(tài)改變:
del demo.__dict__['new_var']模塊在運(yùn)行期可以:
? 動(dòng)態(tài)添加屬性/刪除屬性
? 可被反射、注入、修改
? 作為插件系統(tǒng)的載體
(3)銷毀階段
當(dāng)模塊對(duì)象被垃圾回收時(shí),模塊 __dict__ 隨對(duì)象一同銷毀,其命名空間不再存在。
通常,模塊會(huì)常駐內(nèi)存,因?yàn)?sys.modules 持有對(duì)模塊對(duì)象的強(qiáng)引用。除非顯式從 sys.modules 中刪除,否則模塊對(duì)象及其 __dict__ 會(huì)一直存在。
四、模塊 __dict__ 與屬性訪問機(jī)制
模塊屬性訪問遵循簡(jiǎn)單直接的規(guī)則:
module.attr在屬性存在的情況下,在語義上等價(jià)于:
module.__dict__['attr']二者在異常類型上略有差異。
屬性訪問特點(diǎn):
? 無方法綁定:模塊中的函數(shù)始終是普通函數(shù)對(duì)象。
? 無 MRO 查找:不存在繼承鏈查找。
? 無描述符處理:不涉及 __get__/__set__ 協(xié)議,即使模塊中存在實(shí)現(xiàn)了描述符協(xié)議的對(duì)象,模塊屬性訪問也不會(huì)觸發(fā)描述符綁定邏輯。
? 直接字典查找:屬性訪問就是字典鍵查找。
示例:
demo.f() # 返回 "function",不會(huì)生成方法對(duì)象五、模塊 __dict__ 的典型用途
(1)反射與調(diào)試
可用于枚舉模塊成員、動(dòng)態(tài)分析模塊結(jié)構(gòu)以及 REPL / 調(diào)試器實(shí)現(xiàn)。
pdb.set_trace() # 調(diào)試器內(nèi)部使用 __dict__ 訪問局部變量(2)動(dòng)態(tài)注入 API
常見于插件系統(tǒng)、框架自動(dòng)注冊(cè)以及運(yùn)行期擴(kuò)展接口。
sys.modules[module_name] = module(3)框架自動(dòng)注冊(cè)
return decorator六、不同對(duì)象的命名空間對(duì)比
對(duì)象類型
__dict__ 特性
可變性
特殊行為
實(shí)例
普通 dict
完全可變
支持屬性訪問協(xié)議
mappingproxy
需通過賦值語句
支持繼承、描述符
模塊
普通 dict(完全可寫)
完全可變
直接字典映射
模塊是唯一一個(gè)頂層、全局、完全可變的命名空間對(duì)象,這也是它常被用作配置容器、插件載體、全局狀態(tài)管理的原因。
小結(jié)
模塊 __dict__ 是模塊命名空間的實(shí)體載體,保存了模塊中定義的全部名稱。模塊對(duì)象本質(zhì)上是 types.ModuleType 的實(shí)例,其 __dict__ 是一個(gè)普通、完全可寫的字典。模塊加載時(shí),解釋器創(chuàng)建模塊對(duì)象并逐步填充其 __dict__;運(yùn)行期中,該字典可被動(dòng)態(tài)修改。模塊屬性訪問直接映射到 __dict__ 查找,不涉及方法綁定或 MRO。
理解模塊 __dict__,是理解 Python 命名空間、import 機(jī)制以及動(dòng)態(tài)特性的關(guān)鍵基礎(chǔ)。
![]()
“點(diǎn)贊有美意,贊賞是鼓勵(lì)”
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.