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异常下调用)

猜你喜欢

转载自www.cnblogs.com/shengs/p/12892416.html