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 服务项目调试时需要“附加到进程”,开发体验比较差…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
