国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

Python:類 __dict__ 詳解

0
分享至

在 Python 的對象模型中,類本身也是對象。既然是對象,它就擁有自己的命名空間(namespace),而這個命名空間正是通過類的 __dict__ 屬性來承載的。

如果說實例 __dict__負(fù)責(zé)存儲實例對象的狀態(tài)(State),那么類 __dict__則負(fù)責(zé)定義行為與結(jié)構(gòu)(Behavior & Structure)。深入理解類的 __dict__,是掌握 Python 中類屬性查找、描述符機制、繼承體系以及元編程的關(guān)鍵基礎(chǔ)。

一、類 __dict__ 的本質(zhì):mappingproxy

類 __dict__ 是一個映射對象,存儲了類級命名空間中的所有成員。

print(A.__dict__)

其核心內(nèi)容包括:

? 類屬性:如 x。

? 方法函數(shù):如 f(在類 __dict__ 中以原始函數(shù)形式存在)。

? 描述符對象:property、classmethod、staticmethod。

? 內(nèi)置元數(shù)據(jù):自動生成的屬性如 __module__、__doc__、 __dict__、__weakref__ 等。

類對象的命名空間(即類 __dict__)里存儲的是一切被定義在類體中的對象,而這些對象在被訪問時,會根據(jù)它們是否實現(xiàn)了描述符協(xié)議,表現(xiàn)出不同的身份。

存儲在 A.__dict__ 鍵值對中的鍵 “__dict__”,既不是類 __dict__,也不是實例 __dict__,它對應(yīng)的值是一個 getset_descriptor(屬性描述符)。當(dāng)調(diào)用 obj.__dict__ 時,實際上是觸發(fā)了類中的這個描述符,它負(fù)責(zé)去實例的內(nèi)存地址中通過偏移量找到屬于該實例的 __dict__。

需要注意的是,類 __dict__ 并不是普通的字典(dict):

type(A.__dict__)  #

這意味著它是一個只讀的映射視圖(mappingproxy),不允許進(jìn)行直接修改操作。

# TypeError: 'mappingproxy' object does not support item assignment

Python 的設(shè)計初衷是,類結(jié)構(gòu)的修改必須通過屬性賦值語義(如 setattr(A, 'x', 10) 或 A.x = 10)來完成。

這樣做是為了確保每次修改都能觸發(fā)底層的元類鉤子、更新緩存,并維護(hù)描述符機制以及多繼承體系下的一致行為。

二、生成時機:類創(chuàng)建的“快照”

類 __dict__ 并非在運行期動態(tài)累積生成的,而是在類創(chuàng)建階段一次性生成的。

1、執(zhí)行類體

Python 會先創(chuàng)建一個臨時命名空間(一個普通的字典),順序執(zhí)行類體內(nèi)的代碼。

    def f(self): pass

2、調(diào)用元類

類體執(zhí)行完成后,將該命名空間傳遞給元類(默認(rèn)是 type)。

等價于:

A = type('A', (object,), namespace)

其中 namespace 最終成為 A.__dict__ 的內(nèi)容。

3、封裝視圖

元類完成類對象的實例化,并將該命名空間封裝為 mappingproxy 并綁定到類 __dict__。

因此,類 __dict__ 是類創(chuàng)建完成時的一個結(jié)構(gòu)快照。后續(xù)通過 A.y = 2 等方式添加或修改屬性,實際上會同步更新其底層的映射內(nèi)容。

三、屬性查找鏈中的核心角色

當(dāng)訪問 obj.attr 時,Python 遵循一套嚴(yán)格的查找優(yōu)先級:

1、數(shù)據(jù)描述符:先在類及其父類的 __dict__ 中查找實現(xiàn)了 __set__ 方法的描述符。

2、實例 __dict__:查找實例自身的屬性。

3、非數(shù)據(jù)描述符/普通屬性:在類 __dict__ 中查找方法(如普通函數(shù))或類級變量。

4、父類 __dict__:按照 MRO(方法解析順序) 向上追溯。

5、兜底方案:觸發(fā) __getattr__()。

可見,類 __dict__ 是屬性查找鏈中的核心節(jié)點。方法、屬性、描述符均來源于類 __dict__。

示例:

a.x  # 10(查找 A.__dict__ 得到)

因為 x 存在于 A.__dict__。

四、類 __dict__ 與繼承、MRO 的關(guān)系

(1)子類不會復(fù)制父類 __dict__

# B.__dict__  僅包含 B 新定義的成員,如 y

父類成員通過 MRO 查找,而非物理復(fù)制。

(2)MRO 決定類 __dict__ 的查找順序

屬性的繼承是通過 MRO 鏈條實現(xiàn)的。

# (

 , 

 , 

 )



當(dāng)在 B 的實例中訪問 x 時,Python 先在 B.__dict__ 中查找;若未找到,則根據(jù) B.__mro__ 進(jìn)入 A.__dict__ 查找,以此類推。

B.__dict__  →  A.__dict__  →  object.__dict__

這種機制既保證了內(nèi)存效率(無需冗余拷貝),也保證了動態(tài)性(修改父類時,子類可立即生效)。

五、類 __dict__ 與描述符機制

類 __dict__ 是描述符生效的唯一入口。

A.__dict__['x']  #

訪問 a.x 時,實際上會觸發(fā):

property.__get__(a, A)

描述符必須存在于類的 __dict__ 中才能正常工作。實例的 __dict__ 僅用于存儲數(shù)據(jù),無法承載描述符這類行為邏輯。

六、類 __dict__ 與方法綁定機制

在類 __dict__ 中,所有的實例方法都只是普通的函數(shù)對象:

print(type(A.__dict__['f']))  #

當(dāng)通過實例訪問方法時:

a.f

Python 檢測到函數(shù)對象實現(xiàn)了描述符協(xié)議,于是自動調(diào)用:

function.__get__(a, A)

從而將函數(shù)綁定到實例上,生成一個 Bound Method 對象。

因此,方法定義在類的 __dict__ 中,實例本身并不擁有方法,實例只是提供 self 并完成方法綁定。

七、類 __dict__ 與元類寫入行為

元類可以在類創(chuàng)建階段直接修改即將成為類 __dict__ 的命名空間:

print(A.added)  # 輸出:42

自定義元類時,通過操作 namespace(即未來的 A.__dict__),我們可以實現(xiàn)自動注入屬性、修改類定義等功能:

print(Service.tag)  # 輸出: Processed

ORM 框架(如 Django, SQLAlchemy)正是利用這一點,將類屬性轉(zhuǎn)化為數(shù)據(jù)庫字段的映射。

八、常見誤解與澄清

誤解 1:類屬性存放在實例中

? 錯誤

? 正解:類屬性只存在于類 __dict__ 中。實例僅存儲個性化數(shù)據(jù)。

誤解 2:子類會復(fù)制父類 __dict__

? 錯誤

? 正解:子類僅通過 MRO 查找父類成員,兩者物理隔離。

誤解 3:可以隨意修改 A.__dict__

? 錯誤

? 正解:它是 mappingproxy,必須使用賦值語義(比如 A.attr = v)修改。

誤解 4:方法屬于實例

? 錯誤

? 正解:方法定義在類 __dict__ 中,訪問時通過描述符動態(tài)綁定實例。

小結(jié)

類 __dict__ 是類對象的命名空間,用于存儲類屬性、方法和描述符。它在類創(chuàng)建階段由元類一次性生成,并以只讀的 mappingproxy 形式暴露。類 __dict__ 是屬性查找、方法綁定、描述符生效和繼承體系運作的核心。子類不會復(fù)制父類 __dict__,而是通過 MRO 動態(tài)查找。

理解類 __dict__,有助于深入掌握 Python 的類模型、方法解析順序與元編程機制。


點贊有美意,贊賞是鼓勵

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(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.

相關(guān)推薦
熱點推薦
記者在街頭采訪年輕人“年薪20萬屬于什么水平”,得到的回答令人咋舌!

記者在街頭采訪年輕人“年薪20萬屬于什么水平”,得到的回答令人咋舌!

張曉磊
2025-10-31 09:44:39
要求解放軍動手,斬首賴清德,臺當(dāng)局下令報復(fù),館長要被拿下?

要求解放軍動手,斬首賴清德,臺當(dāng)局下令報復(fù),館長要被拿下?

音樂時光的娛樂
2026-01-12 08:23:07
皇馬克星上線!巴薩真核拉菲尼亞主導(dǎo)超級杯決賽

皇馬克星上線!巴薩真核拉菲尼亞主導(dǎo)超級杯決賽

體壇周報
2026-01-12 09:17:13
伊朗政府宣布全國哀悼三天

伊朗政府宣布全國哀悼三天

界面新聞
2026-01-12 07:03:21
重返季后賽排名,山東男籃6連勝 于德豪5記三分 邱彪愛將輪番爆發(fā)

重返季后賽排名,山東男籃6連勝 于德豪5記三分 邱彪愛將輪番爆發(fā)

替補席看球
2026-01-11 21:40:49
艾滋病新增130萬!很多人中招很冤枉!在外“5不碰”一定要記死

艾滋病新增130萬!很多人中招很冤枉!在外“5不碰”一定要記死

今朝牛馬
2025-12-31 19:31:04
不服!澳洲將帥批U23國足:射1腳就進(jìn)+下半場龜縮 70年代丑陋踢法

不服!澳洲將帥批U23國足:射1腳就進(jìn)+下半場龜縮 70年代丑陋踢法

我愛英超
2026-01-11 22:39:22
中產(chǎn)涌入超市,搶300元羽絨服

中產(chǎn)涌入超市,搶300元羽絨服

中國新聞周刊
2026-01-09 22:13:04
布倫森26+6+8阿夫迪亞25+5 尼克斯終結(jié)開拓者5連勝

布倫森26+6+8阿夫迪亞25+5 尼克斯終結(jié)開拓者5連勝

北青網(wǎng)-北京青年報
2026-01-12 09:51:15
恭喜楊瀚森!中國歷史首人!姚明都沒能做到

恭喜楊瀚森!中國歷史首人!姚明都沒能做到

King迪哥侃球
2026-01-11 21:55:00
伊朗步入十字路口:抗議者焚燒革命衛(wèi)隊總部!撕毀哈梅內(nèi)伊肖像

伊朗步入十字路口:抗議者焚燒革命衛(wèi)隊總部!撕毀哈梅內(nèi)伊肖像

項鵬飛
2026-01-09 19:37:50
閆學(xué)晶事件升級!官媒批評毫不留情,趙家班多人受牽連,麻煩大了

閆學(xué)晶事件升級!官媒批評毫不留情,趙家班多人受牽連,麻煩大了

李健政觀察
2026-01-10 09:25:10
明搶5000萬桶石油后,特朗普轉(zhuǎn)頭才發(fā)現(xiàn):中國連一桶都不肯買了?

明搶5000萬桶石油后,特朗普轉(zhuǎn)頭才發(fā)現(xiàn):中國連一桶都不肯買了?

書紀(jì)文譚
2026-01-11 19:36:13
特朗普:正在考慮干預(yù)伊朗局勢的“強硬選項”

特朗普:正在考慮干預(yù)伊朗局勢的“強硬選項”

新京報政事兒
2026-01-12 09:47:51
年薪50萬遭妻子嫌棄后續(xù):丈夫身份曝光,工資全上交,挨罵是日常

年薪50萬遭妻子嫌棄后續(xù):丈夫身份曝光,工資全上交,挨罵是日常

單手搓核彈
2026-01-06 13:44:21
國乒四大主力全傷了!男隊無人可用全軍覆沒,王皓爭議舉動太落魄

國乒四大主力全傷了!男隊無人可用全軍覆沒,王皓爭議舉動太落魄

三十年萊斯特城球迷
2026-01-11 20:39:33
天妒英才!四川射箭小將鐘翔去世,年僅17歲,長得帥氣剛拿省冠軍

天妒英才!四川射箭小將鐘翔去世,年僅17歲,長得帥氣剛拿省冠軍

天天熱點見聞
2026-01-12 06:03:39
千人殺豬飯后續(xù),晚上呆呆哭了,無人幫她母親收拾,周圍都在直播

千人殺豬飯后續(xù),晚上呆呆哭了,無人幫她母親收拾,周圍都在直播

觀察鑒娛
2026-01-12 09:19:49
沉默4天后,大陸通知全世界,賴清德隨時可能被抓,鄭麗文懸了?

沉默4天后,大陸通知全世界,賴清德隨時可能被抓,鄭麗文懸了?

軒逸阿II
2026-01-11 00:43:40
卡友吐槽:1200公里有17個收費站,內(nèi)蒙走國道比高速還費錢

卡友吐槽:1200公里有17個收費站,內(nèi)蒙走國道比高速還費錢

商用車頭條
2026-01-11 07:03:58
2026-01-12 10:12:49
MediaTea
MediaTea
專業(yè)的數(shù)字媒體、新媒體技術(shù)
1701文章數(shù) 72關(guān)注度
往期回顧 全部

科技要聞

小米二手車價大跳水:SU7半年跌5萬元

頭條要聞

牛彈琴:新的戰(zhàn)爭一觸即發(fā) 美國和以色列可能弄巧成拙

頭條要聞

牛彈琴:新的戰(zhàn)爭一觸即發(fā) 美國和以色列可能弄巧成拙

體育要聞

U23國足形勢:末輪不負(fù)泰國即確保晉級

娛樂要聞

留幾手為閆學(xué)晶叫屈?稱網(wǎng)友自卑敏感

財經(jīng)要聞

揭秘“穩(wěn)賺不賠”的代工項目騙局

汽車要聞

2026款宋Pro DM-i長續(xù)航補貼后9.98萬起

態(tài)度原創(chuàng)

教育
本地
旅游
游戲
公開課

教育要聞

學(xué)霸要怎么培養(yǎng)?我從管理的角度聊一聊!

本地新聞

云游內(nèi)蒙|“包”你再來?一座在硬核里釀出詩意的城

旅游要聞

貴州梅園,體驗感更好了!

為什么我還愿意玩穿越火線?畢竟現(xiàn)在CF玩家流失率那么高

公開課

李玫瑾:為什么性格比能力更重要?

無障礙瀏覽 進(jìn)入關(guān)懷版