当前位置: 首页 > news >正文

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.私有变量 在大多数面向对象的编程语言中&#xff0c;都存在着私有变量&#xff08;private variable&#xff09;的概念&#xff0c;所谓私有变量&#xff0c;就是指通过某种手段&#xff0c;使得对象中的属性或方法无法被外部所访问。 Python 对于私有变量的实现是引入了一…...

【JVM】7种经典的垃圾收集器

文章目录1. 垃圾收集器概述2. Serial 收集器3. ParNew 收集器4. Paraller Scavenge 收集器5. Serial Old收集器6. Parller Old收集器7. CMS 收集器8. Garbage First 收集器本文参考&#xff1a;深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践&#xff08;第3版&#xff…...

2023/2/12总结

滑动窗口&#xff08;1&#xff09;滑动窗口是一种基于双指针的思想&#xff0c;两个指针指向的元素形成一个窗口。一般用于求取数组或字符串的某个子串、子序列、最长最短等最值或者求某个目标值时&#xff0c;并且该问题本身可以通过暴力解决。滑动窗口分为固定窗口和不定窗口…...

Linux之正则表达式

正则表达式是组成“操作”的基本语法&#xff0c;而这些“操作”是应用于Sed和Awk必备的能力。因此只有了解了正则表达式&#xff0c;才能学好Sed和Awk。正则表达式分为基础正则表达式&#xff08;Regular Expression&#xff09;与扩展正则表达式&#xff08;Extended Regular…...

前端高频面试题-HTML和CSS篇(一)

&#x1f4bb; 前端高频面试题-HTML和CSS篇&#xff08;一&#xff09; &#x1f3e0;专栏&#xff1a;前端面试题 &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向…...

Redis 专题总结

1. 什么是Redis &#xff1f; 处理&#xff1a;内容缓存&#xff0c;主要用于处理大量数据的高访问负载。Redis是一款高性能的NOSQL系列的非关系型数据库&#xff0c;NoSQL(NoSQL Not Only SQL)&#xff0c;意即“不仅仅是SQL”&#xff0c;是一项全新的数据库理念&#xff0…...

【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本地存储带来的单点问题&#xff0c;我们一般在高可用监控架构中会使用远程存储&#xff0c;并通过配置prometheus的remote_write和remote_read来对接 远程写优化&#xff1a;remote_write 远程写的原理&#xff1a…...

redis可视工具AnotherRedisDesktopManager的使用

redis可视工具AnotherRedisDesktopManager的使用 简介 Another Redis DeskTop Manager 是一个开源项目&#xff0c;提供了以可视化的方式管理 Redis 的功能&#xff0c;可供免费下载安装&#xff0c;也可以在此基础上进行二次开发&#xff0c;主要特点有&#xff1a; 支持 W…...

【idea】idea生产类注释和方法注释

网上有很多类似的文章&#xff0c;但是我在按照他们的文章设置后&#xff0c;出现了一些问题&#xff0c;因此我这边在解决了问题后&#xff0c;总结一篇文章&#xff0c;发出来给大家借鉴一下。在此先说明一下idea的版本&#xff0c;是2020.1.3 设置动态模板&#xff0c;File…...

jenkins +docker+python接口自动化之jenkins容器安装python3(二)

jenkins dockerpython接口自动化之jenkins容器安装python3&#xff08;二&#xff09; 目录&#xff1a;导读 前提是在docker下已经配置好jenkins容器了&#xff0c;是将python安装在jenkins容器下的 1、先看你的jenkins是否安装好 2、以root权限进入jenkins容器&#xff1…...

go 命令行工具整理

这里会整理可能会使用到的命令行参数&#xff0c;比如 go build、go run&#xff0c;诸如此类。了解这些内容对我们工作会有什么帮助吗&#xff1f;更多的时候&#xff0c;是能让我们理解代码编译的意图&#xff0c;或者&#xff0c;给我们一种排查问题的手段。 比方说&#x…...

RuntimeError: CUDA out of memory

今天在训练模型的时候突然报了显存不够的问题&#xff0c;然后分析了一下&#xff0c;找到了解决的办法&#xff0c;这里记录一下&#xff0c;方便以后查阅。 注&#xff1a;以下的解决方案是在模型测试而不是模型训练时出现这个报错的&#xff01; RuntimeError: CUDA out of…...

Kubernetes1.25中Redis集群部署实例

1、概述我们知道在 Kubernetes 容器编排平台中, 我们可以非常方便的进行应用的扩容缩, 同时也能非常方便的进行业务的迭代&#xff0c;本章主要讲解在Kubernetes1.25搭建Redis单实例和Redis集群主从同步的环境流程步骤, 如果是高频访问重要的线上业务我们最好是部署在物理机器上…...

C++11实现计算机网络中的TCP/IP连接(Windows端)

目录引言1、TCP2、IP2.1 IP路由器3、TCP/IP4、TCP/IP协议C11实现参考文献引言 TCP/IP 指传输控制协议/网际协议&#xff08;Transmission Control Protocol / Internet Protocol&#xff09;。[1] 在TCP/IP协议簇中主要包含以下内容&#xff1a; TCP (传输控制协议) - 应用程序…...

Spring框架自定义实现IOC基础功能/IDEA如何手动实现IOC功能

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用&#xff01; 7.4 自定义Spring IOC 创建新模块&#xff0c;结构如图![[Pasted image 20230210173222.png]] 7.4.1 定义bean相关POJO类 7.4.1.1 定义propertyValue类 /** …...

pip离线安装windows版torch

文章目录前言conda创建虚拟环境安装torchtorch官网在线安装离线手动安装测试是否安装成功后记前言 学习的时候遇到几个机器学习相关的项目&#xff0c;由于不同的项目之间用到的依赖库不太一样&#xff0c;于是想利用conda为不同的项目创建不同的环境方便管理和运行&#xff0…...

Redis核心知识点

Redis核心知识点Redis核心知识点大全五种数据类型redis整合SpringBoot序列化问题渐进式扫描慢查询缓存相关问题数据库和缓存谁先更新缓存穿透缓存雪崩缓存击穿实际应用超卖问题分布式锁全局唯一ID充当消息队列Feed流附近商户签到HyperLogLog实现UV统计持久化RDBAOF持久化小结事…...

14. 最长公共前缀

14. 最长公共前缀 一、题目描述&#xff1a; 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”] 输出&#xff1a;“fl” 示例 2&#xff1a; …...

SignalR注册成Windows后台服务,并实现web前端断线重连

注意下文里面的 SignalR 不是 Core 版本&#xff0c;而是 Framework 下的 本文使用的方式是把 SignalR 写在控制台项目里&#xff0c;再用 Topshelf 注册成 Windows 服务 这样做有两点好处 传统 Window 服务项目调试时需要“附加到进程”&#xff0c;开发体验比较差&#xf…...

别再只盯着细胞比例了!用Xenium数据做小鼠肺腺癌空间邻域分析,手把手教你找到真正的肿瘤边界

空间邻域分析&#xff1a;重新定义肿瘤微环境的生物学边界 在单细胞和空间组学研究中&#xff0c;我们常常陷入一个思维定式——过度关注细胞类型的比例变化&#xff0c;却忽略了细胞在三维空间中的精妙排布所蕴含的关键信息。这种比例优先的思维模式&#xff0c;就像试图通过统…...

C++程序发生崩溃闪退后为什么会自动重启?是因为程序中启用了重启管理器,系统感知到程序异常退出后自动重启程序

最近在使用sdkdemo程序测试我们的SDK功能时&#xff0c;发现当我们关闭程序后&#xff08;程序确实关闭了&#xff09;&#xff0c;程序居然又自动启动起来了&#xff01;后来运行Debug版本的sdkdemo&#xff0c;在关闭程序时会弹出报错提示框&#xff1a;估计是程序在退出时产…...

VHD/VHDX 数据守护:BAT位图校验与修复

VHD/VHDX 数据守护&#xff1a;BAT位图校验与修复VHD&#xff08;Virtual Hard Disk&#xff09;和 VHDX&#xff08;Virtual Hard Disk v2&#xff09;是微软 Hyper-V 等虚拟化平台常用的虚拟磁盘格式。在这些虚拟磁盘文件中&#xff0c;区块分配表&#xff08;Block Allocati…...

嵌入式老鸟总结:Keil警告L15/L16的隐藏陷阱与RTOS适配技巧

Keil多任务开发中的L15/L16警告&#xff1a;从RTOS视角看函数重入与资源竞争 在嵌入式开发中&#xff0c;Keil编译器的L15&#xff08;MULTIPLE CALL TO SEGMENT&#xff09;和L16&#xff08;UNCALLED SEGMENT&#xff09;警告常常被开发者忽视&#xff0c;但在RTOS环境下&…...

字符串拆分合并

贪心算法,最长限制。 import reclass TextFilter:def __init__(self):# 字符映射规则self.char_map = {# 省略号 → 停顿…: ,, ...: ,,: ,,# 破折号 → 停顿——: ,, —: ,,# 书名号 → 直接删除《: , 》: , 〈: , 〉: ,# 其他特殊符号 → 删除*: , /: , #: ,}# 需要保留的…...

亿级并发下的抢票系统架构:从DDD到微服务的实战解析

1. 抢票系统的业务挑战与技术痛点 每年春运期间&#xff0c;12306系统都要面对全球最严苛的高并发考验。2019年春运最高峰日点击量达到1495亿次&#xff0c;相当于每个中国人当天点击了100多次。这种量级的并发请求&#xff0c;如果直接打到数据库上&#xff0c;就算是把阿里云…...

技术赋能B端拓客:号码核验行业的迭代升级与价值深耕,

在数字经济持续深耕的当下&#xff0c;B端市场的竞争逻辑已发生根本性转变&#xff0c;“粗放拓客”逐渐被“精准高效”取代&#xff0c;企业对拓客全流程的效率与成本管控提出了更高要求。号码核验作为B端拓客的前置核心环节&#xff0c;其作用远不止于简单的空号筛查&#xf…...

“吸收液中间冷却与调整填料高度组合应用” — aspenplusv11百万吨碳捕集系统的关键优化策略

aspenplusv11百万吨碳捕集系统&#xff0c;复配胺溶液&#xff0c;工艺流程优化&#xff0c;吸收液中间冷却、调整吸收段填料高度、贫液入塔分流等。 吸收液中间冷却与调整填料高度组合应用凌晨三点的实验室&#xff0c;咖啡杯底结着褐色的垢。盯着Aspen Plus界面里那个持续报警…...

新手友好:基于快马平台快速上手dhnvr416h-hd设备数据监控开发

新手友好&#xff1a;基于快马平台快速上手dhnvr416h-hd设备数据监控开发 最近在做一个物联网项目&#xff0c;需要对接dhnvr416h-hd设备的数据监控功能。作为刚接触这个领域的新手&#xff0c;我发现理解设备数据格式和通信流程是最关键的第一步。好在通过InsCode(快马)平台的…...

Echo:预测智能的一小步,通往通用智能的一大步

来源&#xff1a;机器之心大模型能否预测未来&#xff1f;UniPat AI 构建了一套完整的预测智能基础设施&#xff0c;Echo&#xff0c;包含动态评测引擎、面向未来事件的训练范式和预测专用模型 EchoZ-1.0。在其公开的 General AI Prediction Leaderboard 上&#xff0c;EchoZ-1…...