当前位置: 首页 > 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…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...