__getattr__

__getattr__在当前主流的Python版本中都可用,重载__getattr__方法对类及其实例未定义的属性有效。也就属性是说,如果访问的属性存在,就不会调用__getattr__方法。这个属性的存在,包括类属性和实例属性。

Python官方文档的定义

Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name.

classClassA:

x= 'a'

def __init__(self):

self.y= 'b'

def __getattr__(self, item):return '__getattr__'

if __name__ == '__main__':

a=ClassA()#输出结果 a

print(a.x)#使用实例直接访问实例存在的实例属性时,不会调用__getattr__方法

#输出结果 b

print(a.y)#使用实例直接访问实例不存在的实例属性时,会调用__getattr__方法

#输出结果 __getattr__

print(a.z)

__getattribute__

__getattribute__仅在新式类中可用,重载__getattrbute__方法对类实例的每个属性访问都有效。

Python官方文档的定义

Called unconditionally to implement attribute accesses for instances of the class.

示例代码:

classClassA:

x= 'a'

def __init__(self):

self.y= 'b'

def __getattribute__(self, item):return '__getattribute__'

if __name__ == '__main__':

a=ClassA()#使用实例直接访问存在的类属性时,会调用__getattribute__方法

#输出结果 __getattribute__

print(a.x)#使用实例直接访问实例存在的实例属性时,会调用__getattribute__方法

#输出结果 __getattribute__

print(a.y)#使用实例直接访问实例不存在的实例属性时,也会调用__getattribute__方法

#输出结果 __getattribute__

print(a.z)

运行结果:

__getattribute__

__getattribute__

__getattribute__

另外,当同时定义__getattribute__和__getattr__时,__getattr__方法不会再被调用,除非显示调用__getattr__方法或引发AttributeError异常。

示例代码(__getattr__方法不会再被调用):

classClassA:def __getattr__(self, item):print('__getattr__')def __getattribute__(self, item):print('__getatttribute__')if __name__ == '__main__':

a=ClassA()

a.x

运行结果:

__getatttribute__

由于__getattr__只针对未定义属性的调用,所以它可以在自己的代码中自由地获取其他属性,而__getattribute__针对所有的属性运行,因此要十分注意避免在访问其他属性时,再次调用自身的递归循环。

当在__getattribute__代码块中,再次执行属性的获取操作时,会再次触发__getattribute__方法的调用,代码将会陷入无限递归,直到Python递归深度限制(重载__setter__方法也会有这个问题)。

示例代码(无限递归):

classClassA:

x= 'a'

def __getattribute__(self, item):print('__getattribute__')returnself.itemif __name__ == '__main__':

a=ClassA()

a.x

运行结果引发异常,提示达到最大递归深度

ecursionError: maximum recursion depth exceeded

同时,也没办法通过从__dict__取值的方式来避免无限递归

classClassA:

x= 'a'

def __getattribute__(self, name):return self.__dict__[name]if __name__ == '__main__':

a=ClassA()#无限递归

a.x

为了避免无限递归,应该把获取属性的方法指向一个更高的超类,例如object(因为__getattribute__只在新式类中可用,而新式类所有的类都显式或隐式地继承自object,所以对于新式类来说,object是所有新式类的超类)。

修改代码(避免无限递归循环):

classClassA:

x= 'a'

def __getattribute__(self, item):print('__getattribute__')return super().__getattribute__(self, item)if __name__ == '__main__':

a=ClassA()print(a.x)

运行结果正常:

__getattribute__a

参考资料:

https://docs.python.org/3/reference/datamodel.html

python getattr和getattribute_Python的__getattr__和__getattribute__相关推荐

  1. python getattr和getattribute_python中__getattr__和__getattribute__区别

    重载__getattr__方法对类及其实例未定义的属性有效.如果访问的属性存在,就不会调用__getattr__方法.这个属性的存在,包括类属性和实例属性 classClassA: x= 'a' de ...

  2. python getattr和getattribute_python中__get__、__getattr__、__getattribute__详解

    __get__,__getattr__和__getattribute__(只存在于新式类)都是访问属性的方法,但有一定的区别. object.__getattr__(self, name) 通过实例访 ...

  3. 【7.2】__getattr__、__getattribute__魔法函数

    1 #!/user/bin/env python 2 # -*- coding:utf-8 -*- 3 # __getattr__.__getattribute__ 4 # __getattr__ 就 ...

  4. python getattr和getattribute_getattr与getattribute的区别__

    让我们看看__getattr__和__getattribute__魔术方法的一些简单示例. __getattr__ 每当您请求尚未定义的属性时,Python将调用__getattr__方法.在下面的示 ...

  5. Python getattr() 函数==>获取一个对象的属性值

    描述 getattr() 函数用于返回一个对象属性值. 语法 getattr 语法: getattr(object, name[, default]) 参数 object -- 对象. name -- ...

  6. Python中的getattr、__getattr__、__getattribute__、__get__

    getattr getattr(object, name[, default])是Python的内置函数之一,它的作用是获取对象的属性. 示例 >>> class Foo: ... ...

  7. python getattr和getattribute_详解Python中 __get__和__getattr__和__getattribute__的区别

    引子 假设我们有个类A,其中a是A的实例 a.x时发生了什么?属性的lookup顺序如下: 如果重载了__getattribute__,则调用. a.__dict__, 实例中是不允许有descrip ...

  8. python setattr 代码可读性_python __setattr__、__getattr__、__getattribute__全面详解

    一.属性引用函数 hasattr(obj,name[,default]) getattr(obj,name) setattr(obj,name,value) delattr(obj,name) 二.属 ...

  9. Python--getattr、__getattr__、__getattribute__,倔强一下

    反射前面我们已经学过了,那么为什么还要写这一篇呢,因为__getattribute__这个属性拦截器,但是在某些情况下使用起来,对应的意义不一样.除了属性拦截器之外,它也能跟反射达到类似的效果,至于它 ...

最新文章

  1. windows 将python源代码加密_对源代码进行pyd加密
  2. 开源监控软件ganglia安装手册
  3. Qt Creator构建并运行示例
  4. linux下查看文件及目录个数
  5. 【Hadoop系列】HDFS
  6. mysql 索引未命中_联合索引命中率问题导致SQL查询效率慢的问题
  7. baidumap vue 判断范围_vue中百度地图API的调用
  8. 安装自带python3.6的Anaconda3,并安装tensorflow,导入Pycharm中使用
  9. 【超图+CESIUM】【基础API使用示例】28、超图|CESIUM -【坐标转换】世界坐标转经纬度
  10. 互联网进化论在中国科技论文在线正式发表
  11. Ubuntu系统拼音无法正确打字怎么解决?
  12. 有三类人永远做不了程序员
  13. python海龟绘图-奥运五环
  14. 新物种打造爆品,总共分几步?DeepTalk vol.1
  15. Command——SQL
  16. 聊一聊计算机视觉中常用的注意力机制 附Pytorch代码实现
  17. 消除表情小游戏 【总结】
  18. 关店歇业?当黄金时代成为历史,快时尚品牌的花式自救
  19. Linux ❉ 文件目录中常用命令 pwd / ls 详解
  20. Guitar Pro怎样可以快速打出三连音?

热门文章

  1. Java—Maven的使用
  2. 理解前端组件化、模块化、工程化
  3. 异步组件与withRouter路由方法
  4. js export default
  5. UPC2021个人训练赛第39场 C: 粉兔找妹子(换根dp)
  6. 机器学习与数据挖掘150道题
  7. Android微信分享功能集成开发指南(这一篇就够了)
  8. 详解K8S入口Ingerss
  9. 十六进制与十进制转换
  10. ios调用python_引用ios-和引用ios相关的内容-阿里云开发者社区