Python魔法方法之__getattr__和getattribute

在Python中有这两个魔法方法容易让人混淆:__getattr__和getattribute。通常我们会定义__getattr__而从来不会定义getattribute,下面我们来看看这两个的区别。

__getattr__魔法方法

class MyClass:def __init__(self, x):self.x = xdef __getattr__(self, item):print('{}属性为找到!'.format(item))return None
>>> obj = MyClass(1)
>>> obj.x
1
>>> obj.y
y属性为找到!
None

我们定义一个MyClass类,设置一个实例属性为x,值为1。obj为这个类的实例,获取obj.x返回1,而获取obj.y发现属性找不到,原因是obj的实例变量中不包含y,找不到某属性时会调用__getattr__方法。

**调用__getattr__详细过程如下:**

obj.attr

1.首先会在对象的实例属性中寻找,找不到执行第二步

2.来到对象所在的类中查找类属性,如果还找不到执行第三步

3.来到对象的继承链上寻找,如果还找不到执行第四步

4.调用obj.__getattr__方法,如果用户没有定义或者还是找不到,抛出AttributeError异常,属性查找失败!

class MyClass:def __init__(self, x):self.x = x
>>> obj = MyClass(1)
>>> obj.y
AttributeError: 'MyClass' object has no attribute 'a'

如上代码,没有定义__getattr__魔法方法,又找不到属性,就会抛出异常。

__getattribute__魔法方法

当我们调用对象的属性时,首先会调用__getattribute__魔法方法。

obj.x
obj.__getattribute__(x)

如上代码,这两个代码其实是等价的。当__getattribute__查找失败,就会去调用__getattr__方法。

代码演示

class MyClass:def __init__(self, x):self.x = xdef __getattribute__(self, item):print('正在获取属性{}'.format(item))return super(MyClass, self).__getattribute__(item)
>>> obj = MyClass(2)
>>> obj.x
正在获取属性x
2

我们使用__getattribute__魔法方法时,要返回父类的方法,不然很难写对,下面代码是一个陷阱,会产生递归。

class MyClass:def __init__(self, x):self.x = xdef __getattribute__(self, item):print('正在获取属性{}'.format(item))return self.item>>> obj = MyClass(2)
>>> obj.xFile "xxx", line 11, in __getattribute__print('正在获取属性{}'.format(item))
RecursionError: maximum recursion depth exceeded while calling a Python object

上面的代码看起来似乎是对的,但却调入了递归的陷阱,相当于

def __getattribute__(self, item):print('正在获取属性{}'.format(item))return self.__getattribute__(item)

要十分警惕。

另外,内置的getattr和hasattr也会触发这个魔法方法。

>>> getattr(obj, 'x', None)
正在获取属性x
2
>>> hasattr(obj, 'x', None)
正在获取属性x
True

其他细节需要注意

class MyClass:x = 999def __init__(self, x):self.x = xdef __getattribute__(self, item):print('正在获取属性{}'.format(item))return super(MyClass, self).__getattribute__(item)

上面代码中,定义了一个类属性x和一个实例属性x,这两个属性同名,根据Python语法规则,当对象获取属性x的时候,首先会在实例属性中寻找,如果找不到才回去类属性中查找。

>>> obj = MyClass(2)
>>> print(obj.x)
正在获取属性x
2
>>> del obj.x  #删除了实例属性x
>>> print(obj.x)  #此时访问的是类属性
正在获取属性
999

这样就能印证了上面所说__getattribute__的查找顺序。通常该方法在框架中可能会用到,一般情况下无需使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/312948.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023-12-12LeetCode每日一题(下一个更大元素 IV)

2023-12-12每日一题 一、题目编号 2454. 下一个更大元素 IV二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数,你必须找到对应元素的 第二大 整数。 如果 nums[j] 满足以下条件,那…

【年度征文】回顾2023,迎接2024

转眼一年~~2023又到年底了,CSDN年度征文如约而至!不知不觉又在CSDN平台写了488篇博文,非常感谢CSDN提供的平台,同时也感谢关注和支持博主的粉丝们,在马上到来新的一年里,我会继续努力!也非常感谢…

RocketMQ(Linux版本5.1.4)

1、停止之前的运行服务 [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# sh bin/mqshutdown namesrv No mqnamesrv running. [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# [roottssvr1-c1 rocketmq-all-4.7.0-bin-release]# [roottssvr1-c1 rocketmq-all-4.7.0-bin-r…

数据结构期末复习(2)链表

链表 链表(Linked List)是一种常见的数据结构,用于存储一系列具有相同类型的元素。链表由节点(Node)组成,每个节点包含两部分:数据域(存储元素值)和指针域(指…

数字集成系统设计——逻辑综合

目录 一、概述 1.1 综合的分类 1.2 逻辑综合的基本架构 1.3 逻辑综合的内部流程 1.3.1 RTL代码转译(Translation) 1.3.2 逻辑级优化(Optimization) 1.3.3 工艺映射(Mapping) 二、优化策略 2.1 资源…

【数学建模美赛M奖速成系列】Matplotlib绘图技巧(三)

Matplotlib绘图技巧(三) 写在前面7. 雷达图7.1 圆形雷达图7.2 多边形雷达图 8. 极坐标图 subplot9. 折线图 plot10. 灰度图 meshgrid11. 热力图11.1 自定义colormap 12. 箱线图 boxplot 写在前面 终于更新完Matplotlib绘图技巧的全部内容,有…

本地git服务器的使用

Windows上使用: 首先要在windows开发机上生成密钥: 1.安装git,首先去git官网下载git,https://git-scm.com/downloads,下载.exe格式并安装。 2.从程序目录启动“Git Bash” 3.键入命令:ssh-keygen -t rsa -…

目标检测-Two Stage-Mask RCNN

文章目录 前言一、Mask RCNN的网络结构和流程二、Mask RCNN的创新点总结 前言 前文目标检测-Two Stage-Faster RCNN提到了Faster RCNN主要缺点是: ROI Pooling有两次量化操作,会引入误差影响精度 Mask RCNN针对这一缺点做了改进,此外Mask …

FreeRTOS学习第5篇--任务优先级

目录 FreeRTOS学习第5篇--任务优先级任务优先级设计实验任务一StartDefaultTask任务相关代码片段任务二ColorLED_Test任务相关代码片段任务三IRReceiver_Task相关代码片段实验现象本文中使用的测试工程 FreeRTOS学习第5篇–任务优先级 本文目标:学习与使用FreeRTOS…

使用css实现 Typora markdown 标题自动编号

第一,找到主题文件夹 第二,复制下面代码放入 AutoNumber.css文件中 body {counter-reset: h1; }#write h1, .markdown-section h1 {counter-reset: h2; }#write h2, .markdown-section h2 {counter-reset: h3; }#write h3, .markdown-section h3 {counte…

红队打靶练习:SAR: 1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto 5、whatweb 小结 目录探测 1、gobuster 2、dirsearch WEB CMS 1、cms漏洞探索 2、RCE漏洞利用 提权 get user.txt 本地提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface:…

tp5+workman(GatewayWorker) 安装及使用

一、安装thinkphp5 1、宝塔删除php禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork,执行安装命令。 composer create-project topthink/think5.0.* tp5 --prefer-dist 2、配置好站点之后,浏览器打开访问成…