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

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

Python:__slots__ 詳解

0
分享至

在 Python 中,每個(gè)對(duì)象通常擁有一個(gè)可變字典 __dict__,用于保存屬性。這種結(jié)構(gòu)帶來(lái)了極高的靈活性,我們可以在運(yùn)行時(shí)自由添加或刪除屬性。

然而,靈活性意味著代價(jià):每個(gè)實(shí)例都要維護(hù)獨(dú)立的字典,這會(huì)帶來(lái)顯著的內(nèi)存開(kāi)銷,尤其是在創(chuàng)建大量對(duì)象時(shí)。

為此,Python 提供了一個(gè)優(yōu)化機(jī)制 __slots__,它允許開(kāi)發(fā)者顯式聲明對(duì)象能擁有的屬性,從而避免自動(dòng)生成 __dict__,減少內(nèi)存使用,并加快屬性訪問(wèn)速度。

一、__slots__ 的定義與基本語(yǔ)法

定義:

__slots__ 是類屬性,用于聲明該類實(shí)例允許存在的屬性名稱集合。

語(yǔ)法結(jié)構(gòu):

    __slots__ = ('attr1', 'attr2', ...)

? __slots__ 接受包含字符串的可迭代對(duì)象(通常為元組或列表)。

切勿寫(xiě)成單個(gè)字符串,例如:__slots__ = 'x',它會(huì)被當(dāng)成字符序列。單個(gè)字符串時(shí)應(yīng)寫(xiě)成:

__slots__ = ('x',)

? 被聲明的屬性不再存儲(chǔ)在 __dict__ 中,而是以更緊湊的結(jié)構(gòu)(slot descriptor)保存。

? 若類定義了 __slots__,實(shí)例通常不會(huì)再自動(dòng)創(chuàng)建 __dict__。

示例:

print(p.x, p.y)  # 輸出:1 2

二、 __slots__與 __dict__ 的關(guān)系

(1)正常情況下,每個(gè)對(duì)象都有自己的 __dict__,用于動(dòng)態(tài)存儲(chǔ)屬性:

print(a.__dict__)  # {'x': 10}

(2)使用 __slots__ 后,類不再創(chuàng)建實(shí)例 __dict__:

print(hasattr(B, '__dict__'))  # True:類對(duì)象總有類字典,與實(shí)例無(wú)關(guān)

(3)影響

? 無(wú)法動(dòng)態(tài)添加未在 __slots__ 中聲明的屬性。

? 屬性訪問(wèn)通過(guò)偏移定位,比哈希查找更快(CPython 特性)。

? 內(nèi)存消耗顯著下降,特別是在大量實(shí)例化時(shí)。

三、__slots__ 的設(shè)計(jì)動(dòng)機(jī)

(1)內(nèi)存優(yōu)化

每個(gè)對(duì)象若擁有 __dict__,都要分配一個(gè)獨(dú)立的哈希表。

在成千上萬(wàn)個(gè)對(duì)象的場(chǎng)景中,內(nèi)存占用會(huì)非常大。

__slots__ 通過(guò)為每個(gè)屬性分配固定槽位,大幅節(jié)省這些哈希表開(kāi)銷。

(2)屬性訪問(wèn)性能提升

在 CPython 中,slot 訪問(wèn)通過(guò)靜態(tài)偏移實(shí)現(xiàn),比字典查找更快(但總體屬于微優(yōu)化,主要體現(xiàn)在大規(guī)模對(duì)象上)。

注意:這些優(yōu)化是 CPython 特性,不同實(shí)現(xiàn)(如 PyPy)可能不同。

對(duì)比示例:

        self.y = 2

在創(chuàng)建百萬(wàn)個(gè)實(shí)例時(shí),Slotted 版本通常可節(jié)省數(shù)十 MB 內(nèi)存(依版本而定)。

四、繼承機(jī)制與注意事項(xiàng)

理解 __slots__ 與繼承的交互,是使用它的關(guān)鍵。

(1)父類未定義 __slots__

子類即使定義了 __slots__,實(shí)例仍會(huì)擁有 __dict__。

print(hasattr(B(), '__dict__'))  # True

原因:父類允許動(dòng)態(tài)屬性,子類無(wú)法完全禁止。

(2)父類定義了 __slots__

若父類定義 __slots__,子類若不額外聲明,也不會(huì)有 __dict__:

print(hasattr(Sub(), '__dict__'))  # False

理由:若父類限制了屬性,子類繼承限制。

(3)繼承多個(gè)類時(shí)

如果任意一個(gè)基類有實(shí)例 __dict__(即未聲明 __slots__),合并后的類實(shí)例也將擁有 __dict__:

print(hasattr(C(), '__dict__'))  # True

說(shuō)明:要讓子類完全沒(méi)有 __dict__,MRO 中所有基類都必須聲明 __slots__ 且不要引入 __dict__。

(4)在子類中擴(kuò)展 slots

子類若想增加新的 slot,必須顯式聲明自己的 __slots__,例如:

    __slots__ = ('y',)  # 合并為 ('x', 'y')

如果子類不想新增 slot,也可寫(xiě):

    __slots__ = ()

四、允許同時(shí)擁有 __dict__ 與 __slots__

若希望在使用 __slots__ 的同時(shí)仍能動(dòng)態(tài)添加屬性,可顯式加入 "__dict__":

print(f.__dict__)  # {'new_attr': 'dynamic!'}

這種方式在需要內(nèi)存優(yōu)化又要求部分動(dòng)態(tài)性的場(chǎng)景中很常用。

五、__slots__ 的生命周期與對(duì)象管理

(1)實(shí)例創(chuàng)建

當(dāng)實(shí)例被創(chuàng)建時(shí),解釋器為聲明在 __slots__ 中的屬性預(yù)留固定位置。

這些位置在對(duì)象生命周期內(nèi)保持恒定。

(2)屬性綁定

每次賦值操作只是修改該固定槽位內(nèi)容,無(wú)需動(dòng)態(tài)擴(kuò)展字典。

(3)銷毀與回收

當(dāng)對(duì)象銷毀時(shí),槽位中存儲(chǔ)的引用隨對(duì)象釋放;

若存在循環(huán)引用,依舊由垃圾回收器處理(gc 模塊同樣適用)。

__slots__ 并不會(huì)改變對(duì)象的生命周期,只是改變屬性存儲(chǔ)的形式。

六、常見(jiàn)誤區(qū)與陷阱

(1)誤以為 __slots__ 能提升所有性能

__slots__ 優(yōu)化的是內(nèi)存與屬性訪問(wèn)速度,不會(huì)改變算法性能或 CPU 計(jì)算效率。

(2)忘記繼承中的 __dict__ 回退機(jī)制

父類若未定義 __slots__,子類定義會(huì)失效。

(3)不能用于模塊或函數(shù)

__slots__ 只對(duì)類定義生效。模塊、函數(shù)、內(nèi)置類型無(wú)法使用。

(4)序列化(pickle)兼容性問(wèn)題

某些情況下,只有 slot 的對(duì)象在 pickle 時(shí)需要:

? 定義 __getstate__ / __setstate__

? 或通過(guò) copyreg 注冊(cè)自定義序列化函數(shù)

否則部分 Python 版本可能無(wú)法自動(dòng)保存 slots 中的值。

(5)弱引用支持需要聲明 __weakref__

如需讓實(shí)例可被 weakref 引用,必須加入:

    __slots__ = ('x', '__weakref__')

否則:

weakref.ref(C())  # TypeError

小結(jié)

__slots__ 是 Python(尤其 CPython)中的一種性能優(yōu)化機(jī)制。通過(guò)限制實(shí)例屬性集合,它讓對(duì)象可以使用更緊湊的內(nèi)存結(jié)構(gòu),并加速屬性訪問(wèn)。它在靈活性與效率之間建立平衡,讓 Python 在動(dòng)態(tài)語(yǔ)言中也能獲得接近靜態(tài)語(yǔ)言的數(shù)據(jù)結(jié)構(gòu)效率。


點(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.

相關(guān)推薦
熱點(diǎn)推薦
國(guó)乒顆粒無(wú)收!陳幸同2-4輸世界第7:抗癌斗士1年2冠 排名升至第5

國(guó)乒顆粒無(wú)收!陳幸同2-4輸世界第7:抗癌斗士1年2冠 排名升至第5

風(fēng)過(guò)鄉(xiāng)
2026-01-12 07:03:08
19歲確診強(qiáng)迫癥,40歲金球雙提名:她終于與“瘋狂”的自己和解

19歲確診強(qiáng)迫癥,40歲金球雙提名:她終于與“瘋狂”的自己和解

桃桃淘電影
2026-01-10 11:30:13
李修賢直播祝周星馳一年賺10個(gè)億:都存在銀行,千萬(wàn)別花哦!

李修賢直播祝周星馳一年賺10個(gè)億:都存在銀行,千萬(wàn)別花哦!

動(dòng)物奇奇怪怪
2026-01-12 01:08:36
這是一輪有色金屬(股)的超級(jí)周期

這是一輪有色金屬(股)的超級(jí)周期

和訊網(wǎng)
2026-01-11 21:53:48
特斯拉中國(guó)又推出新優(yōu)惠方案,這也太夸張了!

特斯拉中國(guó)又推出新優(yōu)惠方案,這也太夸張了!

XCiOS俱樂(lè)部
2026-01-11 11:19:46
為什么全國(guó)人民都在拒接電話?連10086打來(lái)也是瞄一眼就掛掉了!

為什么全國(guó)人民都在拒接電話?連10086打來(lái)也是瞄一眼就掛掉了!

今朝牛馬
2026-01-08 16:05:10
2-2!意甲3強(qiáng)一夜不勝,爭(zhēng)冠大局:國(guó)米領(lǐng)先3分,4強(qiáng)緊追有變數(shù)

2-2!意甲3強(qiáng)一夜不勝,爭(zhēng)冠大局:國(guó)米領(lǐng)先3分,4強(qiáng)緊追有變數(shù)

體育知多少
2026-01-12 07:40:42
攝影比賽第一名疑似AI圖片被取消成績(jī) 主辦方:作品不符合原創(chuàng)性規(guī)則

攝影比賽第一名疑似AI圖片被取消成績(jī) 主辦方:作品不符合原創(chuàng)性規(guī)則

封面新聞
2026-01-11 17:01:04
伊朗步入十字路口:抗議者焚燒革命衛(wèi)隊(duì)總部!撕毀哈梅內(nèi)伊肖像

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

項(xiàng)鵬飛
2026-01-09 19:37:50
布拉德利因右膝重傷提前報(bào)銷賽季

布拉德利因右膝重傷提前報(bào)銷賽季

體壇周報(bào)
2026-01-11 20:15:44
善惡有報(bào),2025年塌房的六大網(wǎng)紅,為了流量各種作妖,不值得同情

善惡有報(bào),2025年塌房的六大網(wǎng)紅,為了流量各種作妖,不值得同情

單手搓核彈
2026-01-06 14:04:34
3-2!巴薩擊敗皇馬,捧起超級(jí)杯冠軍!德容飛鏟姆巴佩,吃到紅牌

3-2!巴薩擊敗皇馬,捧起超級(jí)杯冠軍!德容飛鏟姆巴佩,吃到紅牌

齊帥
2026-01-12 05:19:57
2026年慢病報(bào)銷巨變!6種病免辦卡直接省一半錢,大多數(shù)還不知情

2026年慢病報(bào)銷巨變!6種病免辦卡直接省一半錢,大多數(shù)還不知情

復(fù)轉(zhuǎn)這些年
2026-01-11 23:32:18
22分+19分!如此重要的替補(bǔ)火力點(diǎn),當(dāng)初險(xiǎn)些因?yàn)閹?kù)明加錯(cuò)過(guò)簽約

22分+19分!如此重要的替補(bǔ)火力點(diǎn),當(dāng)初險(xiǎn)些因?yàn)閹?kù)明加錯(cuò)過(guò)簽約

移動(dòng)擋拆
2026-01-12 04:38:29
“200億帶貨先生”董宇輝,可能是最后一個(gè)超頭主播

“200億帶貨先生”董宇輝,可能是最后一個(gè)超頭主播

唐辰同學(xué)
2026-01-11 21:54:28
特朗普:將不會(huì)再有石油或資金流入古巴

特朗普:將不會(huì)再有石油或資金流入古巴

財(cái)聯(lián)社
2026-01-11 20:50:05
海底撈就餐送“黃金小馬”沖上熱搜,工作人員:并非純金,是合成金屬材質(zhì)的

海底撈就餐送“黃金小馬”沖上熱搜,工作人員:并非純金,是合成金屬材質(zhì)的

極目新聞
2026-01-11 15:27:52
新加坡終于知道怕了,退居二線的李顯龍,給自己的繼任者敲響警鐘

新加坡終于知道怕了,退居二線的李顯龍,給自己的繼任者敲響警鐘

窺史
2026-01-12 00:08:13
四川省政府原參事、四川大學(xué)電子信息學(xué)院奠基人蘇顯渝逝世

四川省政府原參事、四川大學(xué)電子信息學(xué)院奠基人蘇顯渝逝世

澎湃新聞
2026-01-11 11:42:27
36歲哺乳期媽媽在私人工作室打玻尿酸,喊了聲疼后單眼永久性失明

36歲哺乳期媽媽在私人工作室打玻尿酸,喊了聲疼后單眼永久性失明

半島晨報(bào)
2026-01-11 20:44:48
2026-01-12 08:08:49
MediaTea
MediaTea
專業(yè)的數(shù)字媒體、新媒體技術(shù)
1701文章數(shù) 72關(guān)注度
往期回顧 全部

科技要聞

“我們與美國(guó)的差距也許還在拉大”

頭條要聞

李獻(xiàn)林學(xué)習(xí)教育期間違規(guī)吃喝:5人喝4瓶酒 1人酒后死亡

頭條要聞

李獻(xiàn)林學(xué)習(xí)教育期間違規(guī)吃喝:5人喝4瓶酒 1人酒后死亡

體育要聞

U23國(guó)足形勢(shì):末輪不負(fù)泰國(guó)即確保晉級(jí)

娛樂(lè)要聞

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

財(cái)經(jīng)要聞

外賣平臺(tái)"燒錢搶存量市場(chǎng)"迎來(lái)終局?

汽車要聞

2026款宋Pro DM-i長(zhǎng)續(xù)航補(bǔ)貼后9.98萬(wàn)起

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

游戲
健康
教育
親子
旅游

這款帥到掉渣的GBA神作《洛克人ZERO》,被模仿無(wú)數(shù)次仍是巔峰

這些新療法,讓化療不再那么痛苦

教育要聞

1分鐘說(shuō)清!山西工程科技職業(yè)大學(xué)專業(yè)錄取線

親子要聞

最近的孩子怎么都長(zhǎng)得這么著急?你不說(shuō),誰(shuí)知道他還是個(gè)寶寶?

旅游要聞

生態(tài)優(yōu)先,雪域高原煥發(fā)新生機(jī)(子夜走筆)

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