getattr__与__getattribute
python类中有两个方法__getattr__
与__getattribute__
比较容易搞混,
这里用一个例子对两者关系和区别加以说明
样例代码
class A:
def __init__(self, name):
self.name = name
def __getattr__(self, item):
print(f'__getattr__ {item}')
return item
def __getattribute__(self, item):
print(f'__getattribute__ {item}')
return super(A, self).__getattribute__(item)
if __name__ == '__main__':
a = A('kevin')
name = a.name
print(name)
print('---------------')
age = a.age
print(age)
输出
结果说明
两次获取属性均进入__getattribute__
方法,不同的是name
因为找到了对应属性因此直接返回,而age
因为没有找到而进入了__getattr__
方法,返回值为__getattr__
返回值。
结论
当获取实例属性时会默认调用__getattribute
,如果找到属性则返回,未找到则调用__getattr__
。
getattr()函数
getattr()
函数也可以获取实例属性,还是用上面定义的类举例
if __name__ == '__main__':
a = A('kevin')
name = getattr(a, 'name')
print(name)
print('---------')
age = getattr(a, 'age', 18)
print(age)
输出:
可以看出来getattr(a, 'x')
等同于a.x
,不过getattr还提供了一个默认值参数getattr(a, 'x', default)
,当a中没有x属性时会返回default,值得注意的是当类已经重载了__getattr__
时default会失效,返回值为__getattr__
返回值。