符合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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;广…