符合Python風格的對象(使用 __slots__ 類屬性節省空間)

使用__slots__ 類屬性節省空間

默認情況下,Python 在各個實例中名為__dict__ 的字典里存儲實例屬
性。如 3.9.3 節所述,為了使用底層的散列表提升訪問速度,字典會消
耗大量內存。如果要處理數百萬個屬性不多的實例,通過__slots__
類屬性,能節省大量內存,方法是讓解釋器在元組中存儲實例屬性,而
不用字典。

繼承自超類的__slots__ 屬性沒有效果。Python 只會使用
各個類中定義的__slots__ 屬性。

定義__slots__ 的方式是,創建一個類屬性,使用__slots__ 這個名
字,并把它的值設為一個字符串構成的可迭代對象,其中各個元素表示
各個實例屬性。我喜歡使用元組,因為這樣定義的__slots__ 中所含
的信息不會變化,如示例 9-11 所示。

示例 9-11 vector2d_v3_slots.py:只在 Vector2d 類中添加了__slots__ 屬性

class Vector2d:
__slots__ = ('__x', '__y')
typecode = 'd'
# 下面是各個方法(因排版需要而省略了)

在類中定義__slots__ 屬性的目的是告訴解釋器:“這個類中的所有實
例屬性都在這兒了!”這樣,Python 會在各個實例中使用類似元組的結
構存儲實例變量,從而避免使用消耗內存的__dict__ 屬性。如果有數
百萬個實例同時活動,這樣做能節省大量內存。

如果要處理數百萬個數值對象,應該使用 NumPy 數組(參見
2.9.3 節)。NumPy 數組能高效使用內存,而且提供了高度優化的數值處理函數,其中很多都一次操作整個數組。我定義 Vector2d
類的目的是討論特殊方法,因為我不太想隨便舉些例子。

在示例 9-12 中,我們運行了兩個構建列表的腳本,這兩個腳本都使用
列表推導創建 10 000 000 個 Vector2d 實例。mem_test.py 腳本的命令行
參數是一個模塊的名字,模塊中定義了不同版本的 Vector2d 類。第一
次運行使用的是 vector2d_v3.Vector2d 類(在示例 9-7 中定義),
第二次運行使用的是定義了__slots__ 的
vector2d_v3_slots.Vector2d 類。

示例 9-12 mem_test.py 使用指定模塊(如 vector2d_v3.py)中定義
的 Vector2d 類創建 10 000 000 個實例

$ time python3 mem_test.py vector2d_v3.py
Selected Vector2d type: vector2d_v3.Vector2d
Creating 10,000,000 Vector2d instances
Initial RAM usage: 5,623,808
Final RAM usage: 1,558,482,944
real 0m16.721s
user 0m15.568s
sys 0m1.149s
$ time python3 mem_test.py vector2d_v3_slots.py
Selected Vector2d type: vector2d_v3_slots.Vector2d
Creating 10,000,000 Vector2d instances
Initial RAM usage: 5,718,016
Final RAM usage: 655,466,496
real 0m13.605s
user 0m13.163s
sys 0m0.434s

如示例 9-12 所示,在 10 000 000 個 Vector2d 實例中使用__dict__ 屬
性時,RAM 用量高達 1.5GB;而在 Vector2d 類中定義__slots__ 屬
性之后,RAM 用量降到了 655MB。此外,定義了__slots__ 屬性的版
本運行速度也更快。這個測試中使用的 mem_test.py 腳本其實只用于加
載一個模塊、檢查內存用量和格式化結果,所用的代碼與本章沒有太大
關聯,因此放入附錄 A 中的示例 A-4 里。

在類中定義__slots__ 屬性之后,實例不能再有__slots__ 中所列名稱之外的其他屬性。這只是一個副作用,不是__slots__ 存在的真正原因。不要使用__slots__ 屬性禁止類的
用戶新增實例屬性__slots__ 是用于優化的,不是為了約束程序
員。

然而,“節省的內存也可能被再次吃掉”:如果把__dict__這個名稱
添加到__slots__ 中,實例會在元組中保存各個實例的屬性,此外還
支持動態創建屬性,這些屬性存儲在常規__dict__ 中。當然,把__dict__添加到__slots__ 中可能完全違背了初衷,這取決于各個
實例的靜態屬性和動態屬性的數量及其用法。粗心的優化甚至比提早優
化還糟糕。

此外,還有一個實例屬性可能需要注意,即__weakref__ 屬性,為了
讓對象支持弱引用(參見 8.6 節),必須有這個屬性。用戶定義的類中
默認就有__weakref__ 屬性。可是,如果類中定義了__slots__ 屬
性,而且想把實例作為弱引用的目標,那么要把__weakref__添加
到__slots__ 中。

綜上,slots 屬性有些需要注意的地方,而且不能濫用,不能使用
它限制用戶能賦值的屬性。處理列表數據時__slots__ 屬性最有用,
例如模式固定的數據庫記錄,以及特大型數據集。然而,如果你經常處
理大量數據,一定要了解一下 NumPy(http://www.numpy.org);此外,
數據分析庫 pandas(http://pandas.pydata.org)也值得了解,這個庫可以
處理非數值數據,而且能導入 / 導出很多不同的列表數據格式。slots 的問題
總之,如果使用得當__slots__ 能顯著節省內存,不過有幾點要注
意。
每個子類都要定義__slots__ 屬性,因為解釋器會忽略繼承的__slots__ 屬性。
實例只能擁__slots__ 中列出的屬性,除非把__dict__加
入__slots__ 中(這樣做就失去了節省內存的功效)。

如果不把__weakref__
加入__slots__,實例就不能作為弱引
用的目標。
如果你的程序不用處理數百萬個實例,或許不值得費勁去創建不尋常的
類,那就禁止它創建動態屬性或者不支持弱引用。與其他優化措施一
樣,僅當權衡當下的需求并仔細搜集資料后證明確實有必要時,才應該
使用__slots__ 屬性。
本章最后一個話題討論如何在實例和子類中覆蓋類屬性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82184.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82184.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82184.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

民宿管理系統5

管理員管理&#xff1a; 新增管理員信息&#xff1a; 前端效果&#xff1a; 前端代碼&#xff1a; <body> <div class"layui-fluid"><div class"layui-row"><div class"layui-form"><div class"layui-form-i…

?騰訊地圖軌跡云:重構位置管理的數字神經中樞

——從軌跡追蹤到智能決策&#xff0c;開啟產業互聯網新篇章 在數字經濟與實體經濟深度融合的今天&#xff0c;位置服務已成為企業數字化轉型的核心基礎設施。無論是物流運輸中的車輛調度、共享經濟中的設備管理&#xff0c;還是智慧城市中的交通優化&#xff0c;精準的軌跡數…

rce命令執行原理及靶場實戰(詳細)

2. 原理 在根源上應用系統從設計上要給用戶提供一個指定的遠程命令操作的接口。漏洞主要出現在常見的路由器、防火墻、入侵檢測等設備的web管理界面上。在管理界面提供了一個ping服務。提交后&#xff0c;系統對該IP進行ping&#xff0c;并且返回結果。如果后臺服務器并沒有對…

GeoTools 將 Shp 導入PostGIS 空間數據庫

前言 ? GeoTools 在空間數據轉換處理方面具有強大的能力&#xff0c;能夠高效、簡潔的操縱 Shp 數據。特別是與空間數據庫PostGIS 相結合&#xff0c;更能展示出其空間數據處理的優勢&#xff0c;借助 GeoTools&#xff0c;我們可以實現 Shp 數據高效入庫。 本文上接系列文章 …

基于SpringBoot+Vue的家政服務系統源碼適配H5小程序APP

市場前景 隨著社會經濟的發展和人口老齡化的加劇&#xff0c;家政服務需求不斷增長。我國65歲及以上人口增長較快&#xff0c;2022年我國65歲及以上老年人數量達2.1億人&#xff0c;占比較2016年增長4.1個百分點&#xff0c;達14.9%。我國65歲及以上人口數量龐大&#xff0c;老…

《企業級日志該怎么打?Java日志規范、分層設計與埋點實踐》

大家好呀&#xff01;&#x1f44b; 今天我們要聊一個Java開發中超級重要但又經常被忽視的話題——日志系統&#xff01;&#x1f4dd; 不管你是剛入門的小白&#xff0c;還是工作多年的老司機&#xff0c;日志都是我們每天都要打交道的"好朋友"。那么&#xff0c;如…

1Panel vs 寶塔面板:現代化運維工具的全方位對比

1Panel vs 寶塔面板對比分析 1Panel 和 寶塔面板&#xff08;BT-Panel&#xff09;都是服務器管理工具&#xff0c;旨在簡化 Linux 服務器的運維工作&#xff0c;但它們在設計理念、功能側重點和技術實現上有明顯差異。以下從多個維度對兩者進行對比分析&#xff1a; 1. 定位與…

怎么開發一個網絡協議模塊(C語言框架)之(四) 信號量初始化

// 原始代碼 /* gVrrpInstance.sem = OsixCreateBSem(OSIX_SEM_Q_PRIORITY, OSIX_SEM_FULL); */ gVrrpInstance.sem = OsixCreateMSem(OSIX_SEM_Q_FIFO | OSIX_SEM_DELETE_SAFE); if (gVrrpInstance.sem == NULL) {printf("[VRRP]:vrrp init error, failed to create vrrp…

電腦C盤清理技巧:釋放空間,提升性能

文章目錄 一、使用系統自帶的磁盤清理工具&#xff08;一&#xff09;打開磁盤清理工具&#xff08;二&#xff09;清理臨時文件&#xff08;三&#xff09;清理系統文件 二、使用第三方清理工具&#xff08;一&#xff09;CCleaner&#xff08;極力推薦&#xff09;&#xff0…

ARM筆記-ARM處理器及系統結構

第二章 ARM處理器及系統結構 2.1 ARM處理器簡介 采用RISC架構的ARM微處理器的特點&#xff1a; 體積小、功耗低、低成本、高性能&#xff1b;支持 Thumb&#xff08;16位&#xff09;/ARM&#xff08;32位&#xff09;雙指令集&#xff0c;能很好地兼容 8位/16位 器件&#x…

關于如何在Springboot項目中通過excel批量導入數據

接口文檔 2.5 批量導入學生賬號 2.5.1 基本信息 請求路徑:/admin/students/batch-import 請求方式:POST 接口描述:通過上傳Excel文件批量導入學生賬號信息。 2.5.2 請求參數 參數格式:multipart/form-data 參數說明: 參數名稱參數類型是否必須備注filefile是包含學…

【TypeScript】知識點梳理(四)

#沒事去翻翻官網文檔&#xff0c;其實有很多用法是我們還不知道的&#xff0c;官方資料總是最權威的&#xff0c;也推薦大家無聊看看各個官網hhh&#xff0c;不一定是記憶&#xff0c;但在某種場景下我們或許能想到還有多一種解決方式# noImplicitAny 當我們沒有表明類型時&…

Python匿名函數(lambda)全面詳解

文章目錄 Python匿名函數(lambda)全面詳解一、lambda函數基礎1. 什么是lambda函數&#xff1f;2. lambda函數語法3. 與普通函數的區別 二、lambda函數使用場景1. 作為函數參數2. 在數據結構中使用3. 作為返回值4. 立即調用(IIFE) 三、lambda函數高級用法1. 多參數lambda2. 條件…

Qt Widgets模塊功能詳細說明,基本控件:QCheckBox(三)

一、基本控件&#xff08;Widgets&#xff09; Qt 提供了豐富的基本控件&#xff0c;如按鈕、標簽、文本框、復選框、單選按鈕、列表框、組合框、菜單、工具欄等。 1、QCheckBox 1.1、概述 (用途、狀態、繼承關系) QCheckBox 是 Qt 框架中的復選框控件&#xff0c;用于表示二…

HarmonyOS 鴻蒙應用開發基礎:轉換整個PDF文檔為圖片功能

在許多應用場景中&#xff0c;將PDF文檔的每一頁轉換為單獨的圖片文件是非常有幫助的。這可以用于文檔的分享、掃描文檔的電子化存檔、或者進行進一步的文字識別處理等。本文將介紹如何使用華為HarmonyOS提供的PDF處理服務將整個PDF文檔轉換為圖片&#xff0c;并將這些圖片存放…

【算法】: 前綴和算法(利用o(1)的時間復雜度快速求區間和)

前綴和算法&#xff1a;高效處理區間求和的利器 目錄 引言什么是前綴和前綴和的基本實現前綴和的作用前綴和的典型應用場景前綴和的優缺點分析實戰例題解析 引言 區間求和問題的普遍性暴力解法的時間復雜度問題前綴和算法的核心思想 什么是前綴和 前綴和的數學定義 通俗來…

NDVI諧波擬合(基于GEE實現)

在遙感影像中&#xff0c;我們常用 NDVI&#xff08;歸一化植被指數&#xff09;來衡量地表植被的綠度。它簡單直觀&#xff0c;是生態監測、農情分析的基礎工具。但你是否注意到&#xff1a; NDVI 雖然“綠”&#xff0c;卻常常“亂”。 因為云層、觀測頻率、天氣干擾&#xf…

基于Python+YOLO模型的手勢識別系統

本項目是一個基于Python、YOLO模型、PyQt5的實時手勢識別系統&#xff0c;通過攝像頭或導入圖片、視頻&#xff0c;能夠實時識別并分類不同的手勢動作。系統采用訓練好的深度學習模型進行手勢檢測和識別&#xff0c;可應用于人機交互、智能控制等多種場景。 1、系統主要功能包…

黑馬點評--短信登錄實現

短信登錄 導入黑馬點評項目 導入資料中提供的SQL文件 其中的核心表有&#xff1a; tb_user &#xff1a;用戶表 tb_user_info &#xff1a;用戶詳情表 tb_shop&#xff1a;用戶信息表 tb_shop_type&#xff1a;商戶類型表 tb_blog&#xff1a;用戶日記表&#xff08;達人…

AWS EC2實例安全遠程訪問最佳實踐

EC2 遠程連接方案對比 遠程訪問 Amazon EC2 實例主要有以下四種方式&#xff1a; Secure Shell (SSH) 遠程訪問AWS Systems Manager 會話管理器適用于 Linux 實例的 EC2 Serial ConsoleAmazon EC2 Instance Connect SSH 遠程訪問 SSH&#xff08;Secure Shell&#xff09;廣…