类和对象9:属性访问方法
目录
1. __getattr__(self, item)
2. __getattribute__(self, item)
3. __setattr__(self, key, value)
4. __delattr__(self, item)
1. __getattr__(self, item)
当 item 是一个未定义的属性入口时,在 self.item 上调用 __getattr__ 方法;
如 item 已经存在,或已经由 self 继承,则该方法不被调用;
__getattr__ 方法默认返回异常:AttributeError: type object 'self' has no attribute 'item' ;
通常在默认属性访问,因引发 AttributeError 而失败时被调用,官方文档认为有如下几种可能情况:
- 调用 __getattribute__() 时,item 不是一个实例属性,引发 AttributeError;
- self 的类关系树中属性引发 AttributeError;
- 对 item 特性属性调用 __get__() 时引发了 AttributeError。
__getattr__ 方法重构后应当返回一个对象,或引发一个 AttributeError 异常。
#创建重构 __getatrr__ 方法的类 Test 和实例
class Test:def __init__(self,objname):self.objname = objnamedef __getattr__(self, item):raise OSError('系统错误!')test1 = Test('test1')# item 已存在,该方法不被调用
test1.objname
'test1'
# item 未定义,调用该方法,返回异常
test1.objname1
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 6, in __getattr__
OSError: 系统错误!#创建 Test 的子类 Test_d,并再次重构 __getatrr__ 方法
class Test_d(Test):def __getattr__(self, item):raise AttributeError('未找到该属性!')test2 = Test_d('test2')# item 已被继承,该方法不被调用
test2.objname
'test2'
# item 未定义,调用该方法,返回子类重构定义的异常
test2.objname2
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 3, in __getattr__
AttributeError: 未找到该属性!#默认情况下,返回 AttributeError: type object 'self' has no attribute 'item'
class Test_s:passtest3 = Test_stest3.xyz
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: type object 'Test_s' has no attribute 'xyz'
2. __getattribute__(self, item)
无条件调用该方法,用于实现对类实例属性的访问,如 item 为实例属性时,在 self.item 时被调用;
如果类定义了 __getattr__ 方法,则 __getattr__ 方法仅在 __getattribute__ 方法显式地调用它,或引发了 AttributeError 异常时被调用;
调用 __getattribute__ 方法应当返回(找到的)属性值或是引发一个 AttributeError 异常;
为了避免重构 __getattribute__ 方法导致的无限递归,其实现推荐通过调用父类同名方法来访问它所需要的任何属性,如:super().__getattribute__(item) 。
#创建重构 __getattribute__ 方法的类 Test 和实例
class Test:def __init__(self, objname):self.objname = objnamedef __getattribute__(self, item):attresult = str(super().__getattribute__(item)) + '123'return attresult
test1 = Test('test')#访问实例属性,返回重构后的 __getattribute__ 方法执行结果
test1.objname
'test123'
#访问不存在实例属性,返回默认 __getattre__ 方法执行结果
test1.testinfo
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 6, in __getattribute__
AttributeError: 'Test' object has no attribute 'testinfo'
#设置之前不存在的实例属性,再次访问,返回重构后的 __getattribute__ 方法执行结果
setattr(test1, 'testinfo', 'abcdefg')
test1.testinfo
'abcdefg123'#创建同时重构 __getattribute__、__getattr__ 方法的类 Test2 和实例
class Test2:def __init__(self, objname):self.objname = objnamedef __getattribute__(self, item):attresult = str(super().__getattribute__(item)) + '123'return attresultdef __getattr__(self, item):return f'Sorry, {item} not in!'test2 = Test2('test2')#访问实例属性,按实例属性是否存在,返回重构后的 __getattribute__、__getattr__ 方法执行结果
test2.objname
'test2123'
test2.testinfo
'Sorry, testinfo not in!'
setattr(test2, 'testinfo', 'abcdefg')
test2.testinfo
'abcdefg123'
3. __setattr__(self, key, value)
__setattr__ 方法在 self.key = value 即属性被尝试赋值时被调用;
key 为属性名称, value 为要赋给属性的值,也是实例字典 __dict__ 中保存的键值对;
重构后的 __setattr__ 方法会取代正常机制(即:把属性 key 的值 value 保存到实例字典 __dict__ );
如果 __setattr__ 要赋值给一个实例属性,为了避免重构 __setattr__ 方法导致的无限递归,建议通过如下两种方法实现赋值:
- 调用其父类同名方法,如:super().__setattr__(item, value);
- 给特殊属性实例字典 __dict__ 赋值,如:self.__dict__[item] = value;
#创建重构 __setattr__ 方法的类 Test ,直接使用赋值语句
class Test:def __init__(self, objname):self.objname = objnamedef __setattr__(self, key, value):self.key = value#创建实例对象时,初始化赋值出现无限递归
test1 = Test('test1')
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 3, in __init__File "<input>", line 5, in __setattr__File "<input>", line 5, in __setattr__File "<input>", line 5, in __setattr__[Previous line repeated 985 more times]
RecursionError: maximum recursion depth exceeded#创建重构 __setattr__ 方法的类 Test2 ,使用父类同名方法赋值
class Test1:def __init__(self, objname):self.objname = objname class Test2(Test1):def __setattr__(self, key, value):super().__setattr__(key,value + '123')#初始化赋值和后续赋值,成功返回重构后的 __setattr__ 方法执行结果
test2 = Test2('test2@@')
test2.objname
'test2@@123'
test2.objname = 'abcd@@'
test2.objname
'abcd@@123'#创建重构 __setattr__ 方法的类 Test ,给特殊属性实例字典 __dict__ 赋值
class Test:def __init__(self, objname):self.objname = objnamedef __setattr__(self, key, value):self.__dict__[key] = value + 'xyz'#初始化赋值和后续赋值,成功返回重构后的 __setattr__ 方法执行结果
testx = Test('testx!!')
testx.objname
'testx!!xyz'
testx.objname = 'abcd!!'
testx.objname
'abcd!!xyz'
4. __delattr__(self, item)
__delattr__ 方法在 del self.item 即属性被删除时被调用;
__delattr__ 方法类似于 __setattr__ 方法但其作用为删除而非赋值,仅在 del self.item 对于 self 对象有意义时才被实现;
__delattr__ 方法类似于 __setattr__ 方法,为了避免重构 __setattr__ 方法导致的无限递归,建议通过如下两种方法实现删除:
- 调用其父类同名方法,如:super().__delattr__(item);
- 对特殊属性实例字典 __dict__ 键值对作删除,如:del self.__dict__[item] 。
#创建重构 __delattr__ 方法的类 Test 和实例,直接使用删除语句
class Test:def __init__(self, objname):self.objname = objnamedef __delattr__(self, item):del self.itemtest1 = Test('test1')
test1.objname
'test1'#删除实例对象属性时,出现无限递归
del test1.objname
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 6, in __delattr__File "<input>", line 6, in __delattr__File "<input>", line 6, in __delattr__[Previous line repeated 987 more times]
RecursionError: maximum recursion depth exceeded#创建重构 __delattr__ 方法的类 Test2 ,使用父类同名方法赋值
class Test:def __init__(self, objname):self.objname = objnamedef __delattr__(self, item):del self.__dict__[item]test1 = Test('test1')
test1.objname
'test1'#删除实例对象属性成功
del test1.objname
test1.objname
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'Test' object has no attribute 'objname'#创建重构 __delattr__ 方法的类 Test ,对特殊属性实例字典 __dict__ 中相应键值对做删除
class Test1:def __init__(self, objname):self.objname = objnameclass Test2(Test1):def __delattr__(self, item):super().__delattr__(item)test2 = Test2('test2')
test2.objname
'test2'#删除实例对象属性成功
del test2.objname
test2.objname
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'Test2' object has no attribute 'objname'
类和对象9:属性访问方法相关推荐
- 高阶Day1:面向对象,面向过程,类和对象的属性和方法创建
高阶Day1:面向对象,面向过程,类和对象的属性和方法创建 高级编程学习4个内容: 面向对象 MySQL数据库 网络编程 并发编程 面向过程(POP)与面向对象(OOP): 类和对象: 类名的定义: ...
- 类和对象,属性和方法
1. 定义 类:把某一类事物的属性提取出来,形成类,类有属性(也叫成员变量/field字段)和行为 对象:一个具体的实例 注意:从类到对象的说法:1)创建一个对象2)实例化一个对象3)把类实例化 成员 ...
- 理解Python中的类对象、实例对象、属性、方法
class Animal(object): # 类对象age = 0 # 公有类属性__like = None # 私有类属性def __init__(self): # 魔法方法self.name = ...
- python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...
一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...
- 7.1.3 Python进阶 《函数》定义、调用,参数,返回值《面向对象》概念,类,实例,对象,属性,方法《模块、包》导入,自定义,常用内置:datatime,time,random,os,sys
目录 ======== 第四部分 Python进阶 ======== 第一节 函数 4.1.1 函数定义及调用 4.1.2 函数的参数 4.1.3 函数的返回值 第二节 面向对象 4.2.1 面向对象 ...
- python查看类的属性和方法_Python 获取对象的属性和方法—dir 函数
工作中,我们使用一些之前没用到过的模块,使用时需要了解一下这个模块中的一些类的方法或属性,怎么做呢?目前我比较常用的两款IDE"Pycharm"和"VSCode" ...
- java定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形
定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法 属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形 public class test3 {public ...
- python 判断类是否有某个属性_python判断对象某个属性的方法有哪些
python判断对象某个属性的方法有哪些 发布时间:2020-08-10 15:41:04 来源:亿速云 阅读:92 作者:小新 这篇文章给大家分享的是有关python判断对象某个属性的方法有哪些的内 ...
- 面向对象(类的概念,属性,方法,属性的声明,面向对象编程思维
1 面向对象 1.1 你是如何认识新事物的? 从过往的事物中总结事物的特点(特征),并比对新事物,把新事物进行归类. 1.2 类(Class)的概念(A) 类是对一组具有相同特征和行为的对象的抽象描述 ...
- python属性使用教程_Python对象的属性访问过程详解
只想回答一个问题: 当编译器要读取obj.field时, 发生了什么? 看似简单的属性访问, 其过程还蛮曲折的. 总共有以下几个step: 1. 如果obj 本身(一个instance )有这个属性, ...
最新文章
- Codeforces 337D Book of Evil:树的直径【结论】
- 路由与交换 基础 1:组播
- 计算机视觉编程——图像聚类
- SAP项目MM调研清单
- go函数详解:函数定义、形参、返回值定义规范、函数内存分析、不支持重载、支持可变参数、基本数据类型和数组默认都是值传递的、支持自定义数据类型、函数返回值命名
- CodeForces:749(div1)750(div2)
- 百万年薪大佬熬夜写作,Python高级编程之反爬虫及应对方案
- GitHub标星3.6k | 给AI一张高清照片,分分钟还你3D人体模型
- mfc之CPtrArray数组
- 基于卡尔曼滤波器的回声消除算法
- qemu-nbd挂载虚拟机镜像文件系统
- java与javaw运行jar程序
- 计算机的硬件地址在哪看,电脑的MAC地址在哪里查看
- 金蝶国际:传统ERP增长稳健 转型云服务持续领跑
- win10开始键没反应解决方法
- 打工人:是什么决定了你的薪资水平?一张图带你揭开涨薪秘诀!
- html5光线传感器,基于一种可以测量光线强度的传感器电路设计
- 封禁、下架!微信出手了,规范整治数字藏品平台!
- 被解放的姜戈01 初试天涯
- java版溺尸掉三叉戟吗_《我的世界》一句话评价老MC的富有?萌新:他有54根三叉戟!...
热门文章
- 【有奖倒计时】带你走进AI应用创新大赛十强背后的故事!
- Error Code: 1054. Unknown column 'xxx' in 'field list'
- vant van-calendar日历组件默认选中明天而且只能选择明天
- “cp: 略过目录 “问题
- 【老九学堂】【初识C语言】编译过程
- python 折线图平滑_使用matplotlib的平滑折线图
- 方舟创建专用服务器显示黑框,方舟创建非专用游戏服务器
- 【XGantt教程】为甘特图分组添加舒适排序选项的三个步骤
- 《linux核心应用命令速查》连载五:atq:显示目前使用at命令后待执行的命令队列
- c语言 lis的nlogn算法,LCS (nlogn)