Python高阶知识之属性管理
本文主要介绍Python高阶知识中的属性管理,这部分知识在常规Python编程中用的很少,但对于想深度了解Python甚至有志于自己编写实用框架的人,还是很有必要的,并且如果掌握了,对日常的代码学习等也会有一定好处。
本文结合笔者的经验,以及参考各种专业书籍和文章博客,抽丝剥茧,去掉可能导致混淆不清甚至错误的信息,归总而成,不再废话,直接上文。
一、属性管理概述
属性管理机制主要是为控制对类属性的访问、更新、删除等的操作,借此可实现对属性访问行为的定制化控制,或者变相实现真正的私有属性或变量的需求。
Python随着版本更新和功能演变迭代,大体实现了3大类的属性管理机制,对应应用场景和抽象程度各有不同,以下会分别介绍。
二、具体属性管理手段
2.1 魔法函数重载方法
2.1.1 __setattr__及__getattribute__
这种机制主要借助于Python解释器中属性设置和访问对应魔法函数相关机制:
- Python在访问类或对象属性时,会自动调用__getattribute__魔法函数,当有的时候就返回,没有对应属性的时候,会再调用下面会讲的__getattr__魔法函数
- python在设置或更新属性时,会自动调用__setattr__魔法函数(当然,在设置之前,还是会调用__getattribute__魔法函数确认属性存在)
- 所以可在以上魔法函数内,实现自定义的属性访问及更新等控制机制
class A:def __init__(self):self.name='dennis'def __getattribute__(self,key):#注意,这里需要使用super调用对应方法,否则会循环调用,陷入死循环return super().__getattribute__(key)def __setattr__(self,key,value):#这里可以使用以下两种方式进行属性值更新self.__dict__[key]=valuesuper().__setattr__(key,value)
2.1.2 __getattr__
以下代码即演示,添加了对访问类或对象不存在的属性时自动调用的__getattr__魔法函数,在此可以添加自己的控制或者处理业务逻辑
class A:def __init__(self):self.name='dennis'def __getattribute__(self,key):#注意,这里需要使用super调用对应方法,否则会循环调用,陷入死循环return super().__getattribute__(key)def __setattr__(self,key,value):#这里可以使用以下两种方式进行属性值更新self.__dict__[key]=valuesuper().__setattr__(key,value)def __getattr__(self,key):raise AttributeError(f'error:访问的{key}不存在')
2.2 property内置及延伸方法
2.2.1 property内置方法
上面介绍的通过魔法函数进行属性管理,是对所有属性都进行了管理,本部分主要介绍对指定属性进行管理的机制,也即property内置方法,直接上代码
class A:def __init__(self):self.__name='dennis'def setName(self,value):self.__name=valuedef getName(self):return self.__namedef delName(self):del self.delNamename=property(fget=getName,fset=setName,fdel=delName)
以上代码实现了对name属性的访问、更新、删除的管理,本质类似是一种委托机制,最终修改的是self.__name这个私有属性。
2.2.2 @property装饰器
@property装饰器,是property方法的一种语法变体,最终作用相同,直接贴代码:
class A:def __init__(self):self.__name='dennis'@propertydef name(self):return self.__name@name.setterdef name(self,value):self.__name=value@name.deleterdef name(self):del self.__name
2.3 描述符机制
描述符机制是相对来说抽象程度最深的属性管理机制,其可复用,可继承派生,本质来说,描述符是一种类,这种类内包含有__get__、__set__、__delete__方法的任意一个,而该类的实例会被作为拥有者(owner,即制定属性所属对象)的类属性,当拥有者访问对应属性时,会自动调用描述符类对应的方法。
以上描述比较抽象,具体上代码:
class StringField:def __init__(self,string):self.__string=stringdef __get__(self,instance_obj,owner_class):print('__get__')return self.__stringdef __set__(self,instance_obj,value):print('__set__')self.__string=valuedef __delete__(self,instance_obj):print('__delete__')del self.__stingclass A:name=StringField('dennis')a=A()a.name
a.name='tony'
del a '''
会依次打印出
__get__
__set__
__delete__
'''
以上代码要点解释如下:
- StringField类,即所谓的描述符类,因其包含了指定的方法,其中
- __get__方法内的instance_obj即所属拥有者类对象实例(a)
- owner_class即所属拥有者类(A)
- 可通过这两者访问拥有者类或实例对象的属性或方法
- 在类A内,定义类类属性name,是StringField的实例对象,故
- 当访问、更新、删除类A实例对象a的name属性时,即会自动调用描述符类StringField对应的方法
- 通过以上例子和解释,大家其实会发现,Django框架内的Field,其本质就是一种描述符类,所属拥有者即具体Model类型,Model实例化对象访问这些属性时,会自动调用Field描述符类对应的方法,具体对数据库操作的业务逻辑,就是在这些方法内实现的
所以,了解甚至熟悉描述符,对更好的理解和使用流行框架也是大有益处的。
2.4 其他相关知识
2.4.1 __slots__控制实例对象可定义属性
这个内置属性,可以控制某类实例对象(注意,不包含类属性,以及方法)可定义的属性名范围。相较于不使用__slots__,可显著提升属性访问速度,如果在设计类时,已明确有哪些实例属性,可采用该方式框死属性范围,避免误操作并提升代码执行效率。
class D:__slots__=['name']age=10
如上代码,D类的实力对象只能定义和使用name属性,如果定义其他属性,会引发AttributeError
相关文章:
Python高阶知识之属性管理
本文主要介绍Python高阶知识中的属性管理,这部分知识在常规Python编程中用的很少,但对于想深度了解Python甚至有志于自己编写实用框架的人,还是很有必要的,并且如果掌握了,对日常的代码学习等也会有一定好处。 本文结…...
【Linux】创建目录文件,并完成删除,拷贝,移动,比较等操作
操作前: 1.创建目录 mkdir命令 格式: mkdir 目录名 示例: 点击主文件夹查看 2.创建文件夹 touch命令 格式: touch 文件夹名 示例: 3.重命名文件 mv命令 格式 : mv 123.txt abc.txt 示…...
python http服务搭建教程
作为互联网时代的基础技术之一, HTTP是一个简单的 HTTP协议,它包含了请求、应答和超文本传输控制等机制。HTTP协议由 TCP/IP协议族定义,其中包括了三个基本的服务:发送、接收、存储。客户端和服务器之间传输信息时,数据…...
高速数字信号VS射频信号,到底哪个更难设计?
一博高速先生成员:黄刚熟悉高速先生的小伙伴们会知道,我们是以研究高速数字信号为主的团队,从不到1G到目前在研究的112G,高速先生就这样一直研究过来的,分享的案例也大多是以高速数字信号为主的案例。最近受到我们粉丝…...
相对路径读取json文件 labelme_shapes_to_label 标签
直接读取: import jsonwith open(file.json, r, encodingutf-8) as f:data json.load(f) 忽略错误读取: import jsonimport codecs with codecs.open(file.json, r, encodingutf-8, errorsignore) as f:data json.load(f) labelme_shapes_to_labe…...
IDEA工具避坑指南(十一):git导入SpringBoot后|不识别依赖 |大量爆红 | 无法启动
一、前言 使用在IDEA2019中,使用Git工具导入SpringBoot项目后,java类的依赖包大量爆红、不能启动SpringBoot,不能自动识别启动类。 提示:如果刚拉取的项目,只有.git和.idea文件,没有src或java目录ÿ…...
管道命令(sort、uniq、tr、cut、eval命令)
一、sort命令 1、作用 以行为单位对文件内容进行排序也可以根据不同的数据类型来排序 2、语法格式 sort [选项] 参数cat file | sort 选项3、常用选项 -f∶ 忽略大小写,会将小写字母都转换为大写字母来进行比较; -b∶ 忽略每行前面的空格;…...
Windows10系统忘记登录密码解决办法
Windows10系统忘记登录密码解决办法1. 前言1.1. 环境准备1.2. 官方PE安装系统2. 虚拟机配置2.1. 编辑虚拟机2.2. 进入固件2.3. 编辑启动项顺序2.4. 进入PE系统2.5. 恢复原系统3. 修改程序操作步骤3.1. 调用cmd程序3.2. 查看所有磁盘信息3.3. 进入原系统C盘3.4. 重命名程序3.5. …...
Design Complie实验,使用2007年Synopsy的Lab Guide
Design Complie实验,使用2007年Synopsy的Lab Guide 文章目录Design Complie实验,使用2007年Synopsy的Lab Guide1 DC实验1.1 Setup and Synthesis FlowTask 1 Update the setup fileTask 2 Invoke Design VisionTask 3 Read the Design into DC MemoryTas…...
问题 B: C语言10.2
题目描述: 输入a、b、c三个整数,按先大后小的顺序输出a、b和c。注意请使用指针变量的方式进行比较和输出。 输入 三个用空格隔开的整数a、b和c。 输出 按先大后小的顺序输出a、b和c,用空格隔开。 请注意行尾输出换行。 样例输入 9 0 1…...
多线程控制并发数目工具类Semaphore
文章目录前言Semaphore原理Semaphore源码解析内部继承AQS保证同步acquire获取许可release释放许可实战演示总结前言 在多线程编码过程中,我们会用到多线程来提升运行效率。比如我们的Executors创建线程池,程序尽可能的压榨CPU资源来提升我们程序吞吐量。…...
Redis篇之五大数据类型
1、五大数据类型 4.1、String(字符串) String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象…...
Linux->文件系统磁盘文件管理
目录 1 磁盘结构 2 逻辑抽象管理磁盘 2.1 逻辑抽象 2.2 管理磁盘 2.3 补充知识 3 软硬连接 1 磁盘结构 本篇的学习需要建立在大家在脑海中有一副磁盘的结构才能进行下去,所以我会以图解的方式为大家简单讲解一下,注:博主对这一部分并不是…...
echarts tooltip文字太长换行
tooltip文字太长换行,设置了宽度也没有换行,加上一句: extraCssText: ‘max-width:300px; white-space:pre-wrap’, 没加之前是这样: 加上之后 extraCssText: ‘max-width:300px; white-space:pre-wrap’, tooltip: {trigger: &…...
Docker 部署Jira8.1.0
Jira与Confluence一样,都需要用到独立的数据库,对于数据库的安装我们不做介绍,主要介绍如何用Docker部署Jira以及对Jira进行破解的操作。 1、数据库准备 关于数据库官方文档说明:https://confluence.atlassian.com/adminjiraserv…...
枚举、模拟法(蓝桥杯卡片、数的分解为例)
枚举和模拟算法是计算机领域常用的两种基本算法。枚举算法是一种通过列举所有可能的情况来解决问题的方法。模拟算法则是通过模拟真实场景来解决问题。 枚举、模拟法 枚举算法是指将问题分解为一系列离散的情况,通过枚举所有可能的情况,逐一检查每种情…...
DC-DC升压变换器直流隔离高压输出稳压电源模块5v12v24v48v转50v110v150v220v250v300v350v500v
HRB 系列隔离宽电压输入高电压稳压输出 特点 效率高达 80%以上1*1英寸标准封装单电压输出稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上应用 HRB 0.2~10W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为&#…...
jQuery创建、添加、删除元素
一、创建元素 语法: $("<li></li>"); 动态的创建了一个 <li> 二、添加元素 1. 内部添加 1、element.append(内容) 把内容放入匹配元素内部最后面,类似原生 appendChild。 2、element.prepend(内容) 把内容放入匹…...
产品快讯丨神策数据 A/B 测试试验指标管理重磅升级
神策数据:为了更好地帮助企业管理试验指标,神策数据 A/B 测试完善了指标类型、配置方式、计算原理等,帮助分析师、运营同学等明确计算逻辑,并最大程度减少歧义以及与技术同学沟通的成本,以实现企业内部信息的有效统一。…...
游戏开发之Unity2021URP项目场景的构建
地面的修改和编辑:地面插件的使用 打开包管理器,在左边的包那里选择“Unity注册表”,在右边进行搜索“Polybrush”,之后选择右下角的安装 安装完之后要选择样本中的URP进行导入,因为我们的项目是URP渲染管线的&#x…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
