__getattr__和__getattribute__的区别

版权声明: 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

猜你喜欢

转载自blog.csdn.net/hsc_1/article/details/82946603
今日推荐