Python魔法方法之__getattr__和getattribute

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

__getattr__魔法方法

class MyClass:
    def __init__(self, x):
        self.x = x
    def __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 = x
    def __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 = x
    def __getattribute__(self, item):
        print('正在获取属性{}'.format(item))
        return self.item
        
>>> obj = MyClass(2)
>>> obj.x
  File "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 = 999
    
    def __init__(self, x):
        self.x = x
    def __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__的查找顺序。通常该方法在框架中可能会用到,一般情况下无需使用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

技术博客官网也是一个不错的学习平台(第411篇)

技术博客官网也是一个不错的学习平台(第411篇) 今天的主题是OSPF 大纲 技术成就梦想51CTO-中国知名的数字化人才学习平台和技术社区 OSPF 概念型问题_wx655f0abb3511b的技术博客_51CTO博客 OSPF协议介绍及配置 - airoot - 博客园 (cnblogs.com) 一、OSPF概述 回顾一下距离矢…

python+vue高校体育器材管理信息系统5us4g

优秀的高校体育馆场地预订系统能够更有效管理体育馆场地预订业务规范,帮助管理者更加有效管理场地的使用,有效提高场地使用效率,可以帮助提高克服人工管理带来的错误等不利因素,所以一个优秀的高校体育馆场地预订系统能够带来很大…

通信原理课设(gec6818) 008:LED+蜂鸣器+串口+MQ01+GY39+RFID

目录 1、LED和蜂鸣器 a. 安装驱动 b. 代码 2、串口 3、MQ01烟雾传感器 4、GY39 1、LED和蜂鸣器 a. 安装驱动 在开发板上要使用led和蜂鸣器需要安装对应的驱动 链接:https://pan.baidu.com/s/15I1kGKhT1kENqplu5Dmg5Q?pwdlebe 提取码:lebe 将上…

【并行计算】GPU,CUDA

一、CUDA层次结构 1.kernel核函数 一个CUDA程序是一个kernel核函数被GPU的多个计算单元并行执行的过程&#xff0c;CUDA给了如下抽象 dim3 threadsPerBlock(4, 3, 1); dim3 numBlocks(3, 2, 1); matrixAdd<<<numBlocks, threadsPerBlock>>>(A, B, C); 2.G…

git(安装,常用命令,分支操作,gitee,IDEA集成git,IDEA集成gitee,IDEA集成github,远程仓库操作)

文章目录 1. Git概述1.1 何为版本控制1.2 为什么需要版本控制1.3 版本控制工具1.4 Git简史1.5 Git工作机制1.6 Git和代码托管中心 2. Git安装3. Git常用命令3.1 设置用户签名3.1.1 说明3.1.2 语法3.1.3 案例实操 3.2 初始化本地库3.2.1 基本语法3.2.2 案例实操3.2.3 结果查看 3…

Innosetup 调用c# dll 和 c# dll的函数导出

目标需求&#xff0c;基于现在安装包脚本。需要在用户安装和卸载成功时。进行数据记录,所以需要调用c#dll 主要涉及到的知识点 需要理解脚本的文件使用机制脚本的文件dll加载&#xff0c;和dll的调用c# dll的制作&#xff0c;和工具的使用 下面具体介绍 脚本的文件dll加载&…

详解Vue3中的鼠标事件mousedown、mouseup和contextmenu

本文主要介绍Vue3中的常见鼠标事件mousedown、mouseup和contextmenu。 目录 一、mousedown——鼠标按下事件二、mouseup——鼠标弹起事件三、contextmenu——页面菜单 下面是Vue 3中常用的鼠标事件mousedown、mouseup和contextmenu的详解。 一、mousedown——鼠标按下事件 mo…

CloneNotSupportedException的解决方案 + Object的clone方法分析

CloneNotSupportedException的解决方案 引入问题&#xff1a; 在一次测试clone方法时&#xff0c;D类Override了Object类的clone方法 public class D {private Integer A1;private Integer A2;public D() {}public D(Integer a1, Integer a2 {A1 a1;A2 a2;}Overrideprotec…

PAT 乙级 1042 字符统计

请编写程序&#xff0c;找出一段给定文字中出现最频繁的那个英文字母。 输入格式&#xff1a; 输入在一行中给出一个长度不超过 1000 的字符串。字符串由 ASCII 码表中任意可见字符及空格组成&#xff0c;至少包含 1 个英文字母&#xff0c;以回车结束&#xff08;回车不算在内…

软件测试/测试开发丨Python 内置库 sys 学习笔记分享

sys 概述 是 Python 自带的内置模块是与 Python 解释器交互的桥梁 sys 使用 常用属性常用方法导入 sys 模块 # 导入sys模块 import sys# 查看sys模块帮助文档 help(sys)# 查看sys模块的属性和方法 print(dir(sys))sys 常用属性 sys.version&#xff1a;返回 Python 解释器…

Linux基础知识学习2

tree命令的使用 可以看到dir2目录下的这些文件&#xff0c;要想显示dir2的具体结构&#xff0c;可用tree命令 mv命令 它可以实现两个功能 1.将文件移动到另一个目录中 2.对某一个文件进行重命名 1.将文件移动到另一个目录中 这里将dir1中的2.txt移动到他的子目录dir3中 执行…

虚拟化分类和实现原理

6、虚拟化分类 &#xff08;1&#xff09;完全虚拟化 直接将Hypervisor跑在0环内核态&#xff0c;客户机os跑在1环&#xff0c;一旦触发敏感指令&#xff0c;由0环的VMM进行捕获翻译&#xff0c;从而模 拟这些指令。而运行在1环的GuestOS永远都不知道自己是个虚拟机。是完全…

python统计分析——透视表

参考资料&#xff1a;用Python动手学统计学 pandas库的pivot_table函数相当于excel的透视表功能。此图为excel数据透视表字段设置窗口&#xff0c;下面将参照excel数据透视表相关设置图片学习pivot_table函数&#xff1a; 本次使用的数据集内容如下&#xff1a; import pandas…

python安装MongoDB与运算符优先级

python安装MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一&#xff0c;使用的数据类型 BSON&#xff08;类似 JSON&#xff09;。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动&#xff0c;这里我们使用 PyMongo 驱动来连接。 pip 安装 pip 是一个通用的 Python 包…

【STM32】STM32学习笔记-PWM驱动LED呼吸灯 舵机 直流电机(16)

00. 目录 文章目录 00. 目录01. 输出比较相关API1.1 TIM_OC1Init1.2 TIM_OCInitTypeDef结构体1.3 TIM_OCMode1.4 TIM_OutputState1.5 TIM_OutputNState1.6 TIM_OCPolarity1.7 TIM_OCNPolarity1.8 TIM_OCPolarity1.9 TIM_OCNPolarity 02. PWM实现呼吸灯接线图03. PWM实现呼吸灯示…

普中STM32-PZ6806L开发板(前序)

前言 突然从柜子看到七八年前买的一块普中开发板, 在诸多的例如野火、原子中当时为什么选择他, 现在来看应该还是性价比较高&#xff0c;班上集成了很多学习者的进阶模块了&#xff0c;当然&#xff0c;买完大程度就吃灰了&#xff0c;当我再次发现他的时候&#xff0c; 我看到…

独立站的营销策略:吸引顾客的秘密武器

一、独立站的重要性 独立站是指企业自主建立的电子商务网站&#xff0c;具有独立的域名和运营管理权。通过独立站&#xff0c;企业可以展示产品信息、提供在线服务、进行促销活动等&#xff0c;与顾客建立互动和信任关系。独立站的重要性在于它可以帮助企业建立品牌认知度、提…

【NTN 卫星通信】Oneweb星座以及Oneweb与Starlink比较

1 什么是OneWeb OneWeb于2012年以WorldVu的名义成立&#xff0c;于2020年开始构建其星座。然而&#xff0c;对于这家英国公司来说&#xff0c;这是一个艰难的旅程&#xff0c;OneWeb于2020年3月宣布破产&#xff0c;并认为covid-19大流行是一个主要因素。OneWeb星座当时仅完成…

trino-435: 理论基础

一、trino介绍 Trino是⼀种⽀持使⽤ SQL 访问任意数据源的 开源的分布式SQL 查询引擎&#xff0c;其能够提供更加灵活与⾼效的查询服务。为不同的异构数据源提供统⼀的sql访问&#xff0c;并⽀持联邦查询和并⾏查询。 应⽤场景 Trino是定位在数据仓库和数据分析业务的分布式S…

#前后端分离# 头条发布系统

头条业务简介 新闻的分页浏览通过标题关键字搜索新闻查看新闻详情新闻的修改和删除用户注册、登录 预览界面 开源上线 https://gitcode.net/NVG_Haru/NodeJS_5161447 数据库设计 数据库脚本 CREATE DATABASE sm_db;USE sm_db;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0…