python中__getattr__()和__getattribute__()方法的区别
来源:互联网 发布:vscode php注释插件 编辑:程序博客网 时间:2024/04/30 10:14
在《编写高质量代码–改善python建议》中,看到了__getattr__()
和__getattribute__()
方法的区别,在此一记。 __getattr__()
和__getattribute__()
都是用于实例属性的获取和拦截(仅对实例属性有效,非类属性,类属性通过__set__
和 __get__
),__getattr__()
适用于未定义的属性,而,__getattribute__()
对于所有属性访问都会调用改方法,并且仅用于新式类。
两个区别主要如下:
1. __getattrobute__()
只要涉及到实例属性的访问就会调用该方法,如果属性不存在会抛出AttributeError
异常。
2. __getattr__()
在以下情况下调用:
2.1. 属性不在实例的__dict__
中;
2.2. 属性不在其基类以及祖先类的__dict__
中;
2.3. 出发AttributeError
异常时(不仅仅是__get_attribute__()
引发的异常,property中定义的get()
方法抛出的异常也会调用该方法。)
3. 当__getattr__
和__getattribute__
同时被定义时,要么显示在__getattribute__
中调用,要么抛出AttributeError
异常,否则__getattr__
永远不会被调用。 __getattr__
和__getattribute__
都是Object
类中定义的默认方法,当覆盖这些方法时需要注意几点:
1. 避免无穷递归调用;
2. 访问未定义的属性。如果__getattr__()
方法中不抛出AttributeError
异常或者显示返回一个值,则会返回None,此时可能影响到程序的实际运行预期。
class A(object): def __init__(self, name): self.name = name self.x = 20 def __getattr__(self, name): print('calling __getattr__', name) if name == 'z': return self.x ** 2 elif name == 'y': return self.x ** 3 def __getattribute__(self, attr): try: return super(A, self).__getattribute__(attr) except KeyError: return 'default'a = A('attribute')print(a.name)print(a.z)if hasattr(a, 't'): c = a.t print(c)else: print('instanc a has no attribute t')===================================attribute('calling __getattr__', 'z')400('calling __getattr__', 't')('calling __getattr__', 't')None
如果t不属于实例属性,打印警告信息,否则给c赋值。按照用户的理解本来应该是输出警告信息的,可实际却输出None。因为__getattr__
没用抛出任何异常也没有返回一个值,None被作为默认值返回并且动态添加了t属性。
另外需要注意以下两点
1) 覆盖__getattribute__
方法后,任何属性的访问都会调用用户定义的__getattribute__
方法,性能上回有损耗,比使用默认的方法要慢;
2) 覆盖的__getattr__
方法如果能够动态处理事先未定义的属性,可以更好实现数据隐藏。 __getattribute__()
总会被调用,而__getattr__()
只有在__getattribute__()
中引发异常的情况下才会被调用。
- python中__getattr__()和__getattribute__()方法的区别
- 详解Python中 __get__和__getattr__和__getattribute__的区别
- python中__get__,__getattr__,__getattribute__的区别
- python中__get__,__getattr__,__getattribute__的区别
- python中__getattr__,__setattr__,__getattribute__的区别
- python中__get__,__getattr__,__getattribute__的区别
- python中__get__,__getattr__,__getattribute__的区别
- python __getattribute__ 和 __getattr__的区别
- __getattr__和__getattribute__的区别
- python中__get__, __getattr__和__getattribute__区别说明
- 【Python】4胖学Python - __getattr__() 和 __getattribute__() 方法的区别
- python中__getattribute__与__getattr__调用时的区别
- python:__getattr__() 和 __getattribute__()
- python __getattr__和__getattribute__
- python3中__get__,__getattr__,__getattribute__的区别
- python魔法方法:__getattr__,__setattr__,__getattribute__
- python魔法方法:__getattr__,__setattr__,__getattribute__
- python(第五天):__getattr__ 和 __getattribute__
- 简单使用 Wireshark
- Could not find the main class: org.elasticsearch.bootstrap.Elasticsearch. Program will exit.
- 数组初始化
- 【专题小结】数据结构
- php语言,如何用html代码输出一个网页ob_start&&ob_end_flush
- python中__getattr__()和__getattribute__()方法的区别
- 直接通过ADO操作Access数据库(修改版)
- android设置activity全屏 | 无标题
- VMare虚拟机突破锐捷多网卡限制,成功联网
- Oracle 11g 修改中文字符集
- qt线程,线程池用到的一点问题
- Android中日期时间格式转换
- cocos2dx 重载node绘制基本图形
- javascript 立即执行函数的写法