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…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
