__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