Python中的类和对象(7)
1.私有变量
在大多数面向对象的编程语言中,都存在着私有变量(private variable)的概念,所谓私有变量,就是指通过某种手段,使得对象中的属性或方法无法被外部所访问。
Python 对于私有变量的实现是引入了一种叫 name mangling 的机制(翻译过来叫 “名字改编”、“名称改写” 或者 “名称修饰”),语法是在变量名前面加上两个连续下划线(__):
>>> class C:
... def __init__(self, x):
... self.__x = x
... def set_x(self, x):
... self.__x = x
... def get_x(self):
... print(self.__x)
...
>>> c = C(250)
此时,我们是无法直接通过变量名访问到该变量的:
>>> c.__x
Traceback (most recent call last):File "<pyshell#13>", line 1, in <module>c.__x
AttributeError: 'C' object has no attribute '__x'
想要访问变量的值,就需要使用指定的接口,比如这段代码中的 set_x() 和 get_x() 方法:
>>> c.get_x()
250
>>> c.set_x(520)
>>> c.get_x()
520
2. name mangling 机制的实现原理
我们看看 dict 属性里面有啥:
>>> c.__dict__
{'_C__x': 250}
虽然这里面没有看到 __x,但是,却多了一个 _C__x 的属性对不对?
访问一下试试:
>>> c._C__x
520
果然如此……这个就是传说中的名字改编术!
做法其实也很简单,就是下横线(_)加上类名,再加上变量的名字。
方法名也是同样的道理:
>>> class D:
... def __func(self):
... print("Hello FishC.")
...
>>> d = D()
>>> d.__func()
Traceback (most recent call last):File "<pyshell#12>", line 1, in <module>d.__func()
AttributeError: 'D' object has no attribute '__func'
>>> d._D__func()
Hello FishC.
注意:name mangling 机制是发生在类实例化对象时候的事情,给对象动态添加属性则不会有同样的效果。
3. 不同数量的前缀下划线含义
不同数量的前缀下划线均有不同的特殊含义:

4. 效率的提升之道
Python 对象存储属性的工作原理 —— 字典(dict):
>>> class C:
... def __init__(self, x):
... self.x = x
...
>>> c = C(250)
>>> c.x
250
>>> c.__dict__
{'x': 250}
对象动态添加属性,就是将键值对添加到 dict 中:
>>> c.y = 520
>>> c.__dict__
{'x': 250, 'y': 520}
甚至你可以直接通过给字典添加键值对的形式来创建对象的属性:
>>> c.__dict__['z'] = 666
>>> c.__dict__
{'x': 250, 'y': 520, 'z': 666}
>>> c.z
666
但是,字典高效率的背后是以付出更多存储空间为代价的
如果我们明确知道一个类的对象设计出来,就只是需要那么固定的某几个属性,并且不需要有动态添加属性这样的功能,那么利用字典来存放属性,这种空间上的牺牲就是纯纯地浪费!
针对这个情况,Python 专门设计了一个 _ slots _ 类属性,避免了利用字典存放属性造成空间上的浪费。
举个例子:
>>> class C:
... __slots__ = ['x', 'y']
... def __init__(self, x):
... self.x = x
...
>>> c = C(250)
这样,我们就创建了一个属性受限制的对象。
访问 slots 中列举的属性是没问题的:
>>> c.x
250
>>> c.y = 520
>>> c.y
520
如果想要动态地添加一个属性,那就不好意思了:
>>> c.z = 100
Traceback (most recent call last):File "<pyshell#27>", line 1, in <module>c.z = 100
AttributeError: 'C' object has no attribute 'z'
这种限制不仅体现在动态添加属性上,如果在类的内部,想创建一个 _slots _ 不包含的属性,也是不被允许的:
>>> class D:
... __slots__ = ['x', 'y']
... def __init__(self, x, y, z):
... self.x = x
... self.y = y
... self.z = z
>>> d = D(3, 4, 5)
Traceback (most recent call last):File "<pyshell#8>", line 1, in <module>d = D(3, 4, 5)File "<pyshell#6>", line 6, in __init__self.z = z
AttributeError: 'D' object has no attribute 'z'
甚至是 dict 属性,也不存在了:
>>> d.__dict__
Traceback (most recent call last):File "<pyshell#23>", line 1, in <module>d.__dict__
AttributeError: 'D' object has no attribute '__dict__'
因为使用了 slots 属性,那么对象就会划分一个固定大小的空间来存放指定的属性,这时候 dict 属性就不需要了,空间也就节约了出来。
大家不要小看这点改变……
这里有位国外的老哥,仅仅由于将一个类的三个属性,都改为使用 slots 进行存储,立竿见影地直接节省了 9G 的内存空间

一行代码,竟然降低了 30% 的内存消耗,确实惊人!
不过这里有一点是需要特别强调的,就是使用 slots 属性的副作用其实也相当明显,那就是要以牺牲 Python 动态语言的灵活性,作为前提。
使用了 slots 属性,就没办法再拥有动态添加属性的功能了……
这可以说是它的一个副作用,但实际上很多开发者却利用这个副作用,来限制类属性的滥用。
最后,还有一点需要大家知道的是,继承自父类的 __ slots _ _ 属性是不会在子类中生效的,Python 只关注各个具体的类中定义的 _ _ slots __ 属性:
>>> class E(C):
... pass
...
>>> e = E(250)
>>> e.x
250
>>> e.y = 520
>>> e.z = 666
>>> e.__slots__
['x', 'y']
对象e虽然拥有 slots 属性,但它同时也拥有 dict 属性:
>>> e.__dict__
{'z': 666}
5.思维导图

相关文章:
Python中的类和对象(7)
1.私有变量 在大多数面向对象的编程语言中,都存在着私有变量(private variable)的概念,所谓私有变量,就是指通过某种手段,使得对象中的属性或方法无法被外部所访问。 Python 对于私有变量的实现是引入了一…...
【JVM】7种经典的垃圾收集器
文章目录1. 垃圾收集器概述2. Serial 收集器3. ParNew 收集器4. Paraller Scavenge 收集器5. Serial Old收集器6. Parller Old收集器7. CMS 收集器8. Garbage First 收集器本文参考:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版ÿ…...
2023/2/12总结
滑动窗口(1)滑动窗口是一种基于双指针的思想,两个指针指向的元素形成一个窗口。一般用于求取数组或字符串的某个子串、子序列、最长最短等最值或者求某个目标值时,并且该问题本身可以通过暴力解决。滑动窗口分为固定窗口和不定窗口…...
Linux之正则表达式
正则表达式是组成“操作”的基本语法,而这些“操作”是应用于Sed和Awk必备的能力。因此只有了解了正则表达式,才能学好Sed和Awk。正则表达式分为基础正则表达式(Regular Expression)与扩展正则表达式(Extended Regular…...
前端高频面试题-HTML和CSS篇(一)
💻 前端高频面试题-HTML和CSS篇(一) 🏠专栏:前端面试题 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向…...
Redis 专题总结
1. 什么是Redis ? 处理:内容缓存,主要用于处理大量数据的高访问负载。Redis是一款高性能的NOSQL系列的非关系型数据库,NoSQL(NoSQL Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念࿰…...
【Python百日进阶-Web开发-Vue3】Day515 - Vue+ts后台项目2:登录页面
文章目录 一、创建登录路由1.1 安装 Vue VSCode Snippets插件1.2 处理路径引用的红色波浪线1.3 入口文件 main.ts1.4 主组件 App.vue1.5 路由文件 router/index.ts1.6 首页组件 views/HomeView.vue1.7 登录组件 views/LoginView.vue二、实现登录页面的表单展示2.1 element-plus…...
【博客620】prometheus如何优化远程读写的性能
prometheus如何优化远程读写的性能 场景 为了解决prometheus本地存储带来的单点问题,我们一般在高可用监控架构中会使用远程存储,并通过配置prometheus的remote_write和remote_read来对接 远程写优化:remote_write 远程写的原理:…...
redis可视工具AnotherRedisDesktopManager的使用
redis可视工具AnotherRedisDesktopManager的使用 简介 Another Redis DeskTop Manager 是一个开源项目,提供了以可视化的方式管理 Redis 的功能,可供免费下载安装,也可以在此基础上进行二次开发,主要特点有: 支持 W…...
【idea】idea生产类注释和方法注释
网上有很多类似的文章,但是我在按照他们的文章设置后,出现了一些问题,因此我这边在解决了问题后,总结一篇文章,发出来给大家借鉴一下。在此先说明一下idea的版本,是2020.1.3 设置动态模板,File…...
jenkins +docker+python接口自动化之jenkins容器安装python3(二)
jenkins dockerpython接口自动化之jenkins容器安装python3(二) 目录:导读 前提是在docker下已经配置好jenkins容器了,是将python安装在jenkins容器下的 1、先看你的jenkins是否安装好 2、以root权限进入jenkins容器࿱…...
go 命令行工具整理
这里会整理可能会使用到的命令行参数,比如 go build、go run,诸如此类。了解这些内容对我们工作会有什么帮助吗?更多的时候,是能让我们理解代码编译的意图,或者,给我们一种排查问题的手段。 比方说&#x…...
RuntimeError: CUDA out of memory
今天在训练模型的时候突然报了显存不够的问题,然后分析了一下,找到了解决的办法,这里记录一下,方便以后查阅。 注:以下的解决方案是在模型测试而不是模型训练时出现这个报错的! RuntimeError: CUDA out of…...
Kubernetes1.25中Redis集群部署实例
1、概述我们知道在 Kubernetes 容器编排平台中, 我们可以非常方便的进行应用的扩容缩, 同时也能非常方便的进行业务的迭代,本章主要讲解在Kubernetes1.25搭建Redis单实例和Redis集群主从同步的环境流程步骤, 如果是高频访问重要的线上业务我们最好是部署在物理机器上…...
C++11实现计算机网络中的TCP/IP连接(Windows端)
目录引言1、TCP2、IP2.1 IP路由器3、TCP/IP4、TCP/IP协议C11实现参考文献引言 TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)。[1] 在TCP/IP协议簇中主要包含以下内容: TCP (传输控制协议) - 应用程序…...
Spring框架自定义实现IOC基础功能/IDEA如何手动实现IOC功能
继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用! 7.4 自定义Spring IOC 创建新模块,结构如图![[Pasted image 20230210173222.png]] 7.4.1 定义bean相关POJO类 7.4.1.1 定义propertyValue类 /** …...
pip离线安装windows版torch
文章目录前言conda创建虚拟环境安装torchtorch官网在线安装离线手动安装测试是否安装成功后记前言 学习的时候遇到几个机器学习相关的项目,由于不同的项目之间用到的依赖库不太一样,于是想利用conda为不同的项目创建不同的环境方便管理和运行࿰…...
Redis核心知识点
Redis核心知识点Redis核心知识点大全五种数据类型redis整合SpringBoot序列化问题渐进式扫描慢查询缓存相关问题数据库和缓存谁先更新缓存穿透缓存雪崩缓存击穿实际应用超卖问题分布式锁全局唯一ID充当消息队列Feed流附近商户签到HyperLogLog实现UV统计持久化RDBAOF持久化小结事…...
14. 最长公共前缀
14. 最长公共前缀 一、题目描述: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”] 输出:“fl” 示例 2: …...
SignalR注册成Windows后台服务,并实现web前端断线重连
注意下文里面的 SignalR 不是 Core 版本,而是 Framework 下的 本文使用的方式是把 SignalR 写在控制台项目里,再用 Topshelf 注册成 Windows 服务 这样做有两点好处 传统 Window 服务项目调试时需要“附加到进程”,开发体验比较差…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
