目录

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:属性访问方法相关推荐

  1. 高阶Day1:面向对象,面向过程,类和对象的属性和方法创建

    高阶Day1:面向对象,面向过程,类和对象的属性和方法创建 高级编程学习4个内容: 面向对象 MySQL数据库 网络编程 并发编程 面向过程(POP)与面向对象(OOP): 类和对象: 类名的定义: ...

  2. 类和对象,属性和方法

    1. 定义 类:把某一类事物的属性提取出来,形成类,类有属性(也叫成员变量/field字段)和行为 对象:一个具体的实例 注意:从类到对象的说法:1)创建一个对象2)实例化一个对象3)把类实例化 成员 ...

  3. 理解Python中的类对象、实例对象、属性、方法

    class Animal(object): # 类对象age = 0 # 公有类属性__like = None # 私有类属性def __init__(self): # 魔法方法self.name = ...

  4. python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...

    一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...

  5. 7.1.3 Python进阶 《函数》定义、调用,参数,返回值《面向对象》概念,类,实例,对象,属性,方法《模块、包》导入,自定义,常用内置:datatime,time,random,os,sys

    目录 ======== 第四部分 Python进阶 ======== 第一节 函数 4.1.1 函数定义及调用 4.1.2 函数的参数 4.1.3 函数的返回值 第二节 面向对象 4.2.1 面向对象 ...

  6. python查看类的属性和方法_Python 获取对象的属性和方法—dir 函数

    工作中,我们使用一些之前没用到过的模块,使用时需要了解一下这个模块中的一些类的方法或属性,怎么做呢?目前我比较常用的两款IDE"Pycharm"和"VSCode" ...

  7. java定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形

    定义一个长方形类,该类中具有长方形长宽两种属性,并具有相应的构造方法 属性访问方法,计算长方形的周长和面积的方法,要求输出长是5,宽是4的长方形 public class test3 {public ...

  8. python 判断类是否有某个属性_python判断对象某个属性的方法有哪些

    python判断对象某个属性的方法有哪些 发布时间:2020-08-10 15:41:04 来源:亿速云 阅读:92 作者:小新 这篇文章给大家分享的是有关python判断对象某个属性的方法有哪些的内 ...

  9. 面向对象(类的概念,属性,方法,属性的声明,面向对象编程思维

    1 面向对象 1.1 你是如何认识新事物的? 从过往的事物中总结事物的特点(特征),并比对新事物,把新事物进行归类. 1.2 类(Class)的概念(A) 类是对一组具有相同特征和行为的对象的抽象描述 ...

  10. python属性使用教程_Python对象的属性访问过程详解

    只想回答一个问题: 当编译器要读取obj.field时, 发生了什么? 看似简单的属性访问, 其过程还蛮曲折的. 总共有以下几个step: 1. 如果obj 本身(一个instance )有这个属性, ...

最新文章

  1. Codeforces 337D Book of Evil:树的直径【结论】
  2. 路由与交换 基础 1:组播
  3. 计算机视觉编程——图像聚类
  4. SAP项目MM调研清单
  5. go函数详解:函数定义、形参、返回值定义规范、函数内存分析、不支持重载、支持可变参数、基本数据类型和数组默认都是值传递的、支持自定义数据类型、函数返回值命名
  6. CodeForces:749(div1)750(div2)
  7. 百万年薪大佬熬夜写作,Python高级编程之反爬虫及应对方案
  8. GitHub标星3.6k | 给AI一张高清照片,分分钟还你3D人体模型
  9. mfc之CPtrArray数组
  10. 基于卡尔曼滤波器的回声消除算法
  11. qemu-nbd挂载虚拟机镜像文件系统
  12. java与javaw运行jar程序
  13. 计算机的硬件地址在哪看,电脑的MAC地址在哪里查看
  14. 金蝶国际:传统ERP增长稳健 转型云服务持续领跑
  15. win10开始键没反应解决方法
  16. 打工人:是什么决定了你的薪资水平?一张图带你揭开涨薪秘诀!
  17. html5光线传感器,基于一种可以测量光线强度的传感器电路设计
  18. 封禁、下架!微信出手了,规范整治数字藏品平台!
  19. 被解放的姜戈01 初试天涯
  20. java版溺尸掉三叉戟吗_《我的世界》一句话评价老MC的富有?萌新:他有54根三叉戟!...

热门文章

  1. 【有奖倒计时】带你走进AI应用创新大赛十强背后的故事!
  2. Error Code: 1054. Unknown column 'xxx' in 'field list'
  3. vant van-calendar日历组件默认选中明天而且只能选择明天
  4. “cp: 略过目录 “问题
  5. 【老九学堂】【初识C语言】编译过程
  6. python 折线图平滑_使用matplotlib的平滑折线图
  7. 方舟创建专用服务器显示黑框,方舟创建非专用游戏服务器
  8. 【XGantt教程】为甘特图分组添加舒适排序选项的三个步骤
  9. 《linux核心应用命令速查》连载五:atq:显示目前使用at命令后待执行的命令队列
  10. c语言 lis的nlogn算法,LCS (nlogn)