python __getattr__和__getattribute__ 区别
当我们访问一个对象的不存在的属性的时候,默认都会报错
例如:
class Count(object): def __init__(self, mymin, mymax): self.mymin = mymin self.mymax = mymax
obj1 = Count(1, 10) print(obj1.mymin) print(obj1.mymax) print(obj1.current)
AttributeError: 'Count' object has no attribute 'current'
如果对象中存在这个__getattr__方法呢?
class Count(object): def __init__(self, mymin, mymax): self.mymin = mymin self.mymax = mymax def __getattr__(self, item): self.__dict__[item]=0 return 0
obj1 = Count(1, 10) print(obj1.mymin) print(obj1.mymax) print(obj1.current)
没有的属性会调用这个__getattr__方法,从而obj1.current输出是0
因此我们可以总结:__getattr__表示的是当一个对象访问一个属性时,没有从它定义的属性当中查找到就会调用这个方法。
那有的人可能会问它和__getattribute__方法有什么区别吗?先来看一下一个例子:
class Count(object): def __init__(self, mymin, mymax): self.mymin = mymin self.mymax = mymax def __getattr__(self, item): self.__dict__[item]=0 return 0 def __getattribute__(self, item): print("get object attr: "+item) if item.startswith('cur'): raise AttributeError return object.__getattribute__(self, item) # or you can use ---return super().__getattribute__(item) obj1 = Count(1, 10) print(obj1.mymin) print(obj1.mymax) print(obj1.current)
结果是:
get object attr: mymin
1
get object attr: mymax
10
get object attr: current
get object attr: __dict__
0
从结果可以看出来:默认是首先会调用__getattribute__方法,这里我抛出了一个异常,如果属性名是cur开头的抛出异常,可是为什么结果没有异常呢?
原因是: attribute异常默认会去调用__getattr__这个方法。
所以结果一目了然。
从以上可以总结:
python __getattr__方法是在不存在__getattribute__下,访问不存在的属性下调用的(也可以描述成存在attribute异常下调用)