版权声明: https://blog.csdn.net/hsc_1/article/details/82946603
对于一个对象来说,你需要管理这个对象的属性。
通常我们通过instance.attribute来获取对象的属性。
但是呢,有的时候我们可能需要更多的控制。
通过__getattr__你可以用来处理instance并不拥有的属性。
class Color:
a = 'red'
b = 'blue'
def __getattr__(self, item):
return 'whatever'
c = Color()
c.a #'red'
c.b #'blue'
c.c #'whatever'
c.d #'whatever'
显然,Color类并不拥有属性c和d,但是可以通过__getattr__对其并不包含的属性进行控制,上面的例子就是对不是Color的属性都返回'whatever'。
如果你需要抓取每个属性,而不管这个属性是否存在,那么可以使用__getattribute__
下面的代码可以显示两者的区别
class Color:
red = 'red'
def __getattr__(self, item):
# 在实例没有item属性的时候,调用该方法
print("getattr is being called")
return 'whatever'
def __getattribute__(self, item):
# 实例有没有item属性,都会调用该方法
print("getattribute is being called")
return super().__getattribute__(item)
color = Color()
print(color.red)
print(color.blue)
输出的结果如下
getattribute is being called
red
getattribute is being called
getattr is being called
whatever
可以明显的看出来的就是,不管打印是否是color的属性,首先都是调用的Color的__getattribute__方法,而只有在访问不是color的属性blue的时候,才调用Color的__getattr__方法。
需要注意的是,__getattribute__最好不要随便使用,因为非常容易引起无限递归。
例如,如下的代码就会造成无限递归
扫描二维码关注公众号,回复:
3554282 查看本文章
class Foo(object):
def __init__(self, a):
self.a = 1
def __getattribute__(self, attr):
try:
return self.__dict__[attr]
except KeyError:
return 'default'
f = Foo(1)
f.a