__getattr__
当__getattribute__没有手动定义时,若用户访问了不存在的对象,或者对象的属性不存在时,调用此函数。
__getattribute__
定义此方法后,优先调用。
几个例子:
1. __getattr__与__getattribute__的调用顺序
class A:
def __getattr__(self, item):
print(1)
def __getattribute__(self, item):
print(2)
def __setattr__(self, key, value):
print(3)
def __delete__(self, instance):
print(4)
a = A()
a.x
a.x = 10
a.x
print(a.x)
结果
2
3
2
2
None
逐步分析:首先,由于类中没有x,所以当运行a.x的时候,系统会调用__getattribute__(self, item)函数,或许会有人疑惑:“哎?为什么x这个属性明明没有设定,但却调用了__getattribute__(self, item)?为什么没有调用__getattr__?”
这就是第一个重点了,当用户自己定义了__getattribute__(self, item)函数,那么就会无条件(不管有没有这个属性)优先调用__getattribute__(self, item)函数了。
那么例1中的代码就一目了然了,首先调用了__getattribute__(self, item),打印2,随后调用__setattr__(self, key, value),打印3,由于__setattr__(self, key, value)并没有规定返回值,所以x并没有被定义,a.x相当于None
2. 为__getattribute__(self, item)设定返回值
class A:
def __getattr__(self, item):
print(1)
def __getattribute__(self, item):
print(2)
return super().__getattribute__(item)
def __setattr__(self, key, value):
print(3)
return super().__setattr__(key, value)
def __delete__(self, instance):
print(4)
a = A()
a.x
a.x = 10
a.x
print(a.x)
结果
2
1
3
2
2
10
分析:为什么这里会打印出1这个值呢?即为什么函数__getattr__(self, item)被调用了呢?仔细一看,原来对__getattribute__(self, item)添加了返回值
def __getattribute__(self, item):
print(2)
return super().__getattribute__(item)
也就是说,这次执行代码的时候,系统还是优先调用__getattribute__(self, item),打印2,随后调用super().__getattribute__(item),由于找不到x,系统就会按照object里的方法__getattribute__(self, item)调用__getattr__(self, item),然后打印1
本文详细探讨Python中的魔法方法`__getattr__`和`__getattribute__`,解释它们在对象属性访问时的调用顺序及应用场景。通过实例分析,展示了当对象属性不存在时,如何自定义返回值,以及这两个方法如何影响属性查找过程。
1118

被折叠的 条评论
为什么被折叠?



