python 中__getattr__和__getattribute__使用

初学Python,以下纯属个人理解,若有不对之处或者不完整之处,还请各位前辈指教。

当一个实例对象访问一个属性时,Python解释器搜索该属性的顺序为:

  1. 首先会在实例对象的 "__dict__"属性里面找看有没有这个属性,如test.__dict__
  2. 若没有,则Python解释器会去该实例对象所属的类的"__dict__"属性里面去找, 如Test.__dict__
  3. 如果还是没有的话,则Python解释器会去访问__getattr__这个方法,若没有定义该方法,则会产生AttributeError异常。

__getattribute__用法

  • 当访问实例属性时,不管该实例属性是否存在,必定先调用__getattribute__方法。即对应于上述的 1 和 2 。通常可以在此方法中做相应的处理,比如不同用户组可以访问不同的属性。
  • 由于调用实例属性时必定调用该方法,所以切记不能在此方法中再调用实例属性,以免造成死循环。

__getattr__用法:

  • 用于当调用未定义的属性时的相应处,即是调用属性时,寻找的最后一处,若此处得不到相应的处理,则会引发AttributeError.

贴下代码:

class Test(object):
    def __init__(self):
        self.attr1 = "attribute 1"

    def __getattr__(self,item):
        print("*"*9)
        if item == "add1":
            print("------add1------")
            return "add1"
        else:
            print("新建属性:%s"%item)
            return item

    def __getattribute__(self,item):
        if item == "attr1":
            return "--attribute 1--"
        else:
            print("there is no this attribute ")
            raise AttributeError


if __name__ == "__main__":
    t = Test()
    print(t.attr1)
    print(t.add1)
    print(t.add3)

运行结果:
python 中__getattr__和__getattribute__使用
可以看到当调用 t.attr1 时,得到的返回值是__getattribute__方法里面的返回值,而当调用 t.add1 时在__getattribute__方法里面产生异常之后会调用__getattr__方法。