https://docs.python.org/zh-cn/3/reference/datamodel.html#customizing-attribute-access
__getattr__
__getattribute__
__setattr__
__getattr__与__getattribute__均是一般实例属性截取函数(generic instance attribute interception method),其中,__getattr__可以用在python的所有版本中,
而__getattribute__只可以用到新类型类中(New-style class),其主要的区别是__getattr__只截取类中未定义的属性,而__getattribute__可以截取所有属性
实例instance
通过instance.name
访问属性name
,只有当属性name
没有在实例的__dict__
或它构造类的__dict__
或基类的__dict__
中没有找到,才会调用__getattr__
。
当属性name
可以通过正常机制追溯到时,__getattr__
是不会被调用的。如果在__getattr__(self, attr)
存在通过self.attr
访问属性,会出现无限递归错误。
object.__getattribute__(self, name) 实例`instance`通过`instance.name`访问属性`name`,`__getattribute__`方法一直会被调用,无论属性`name`是否追溯到。
如果类还定义了`__getattr__`方法,除非通过`__getattribute__`显式的调用它,或者`__getattribute__`方法出现`AttributeError`错误,否则`__getattr__`方法不会被调用了。
如果在`__getattribute__(self, attr)`方法下存在通过`self.attr`访问属性,会出现无限递归错误。
class Test: def __getattr__(self, item): # 当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发 print('调用__getattr__方法') # object.__getattribute__(self, item) # return 100 def __getattribute__(self, item): # 查找属性的时候第一时间触发该方法找属性 print('调用__getattribute__方法') # return 100 # return super().__getattribute__(item) def __setattr__(self, key, value): # 这个方法在给对象设置属性的时候触发 print('调用__setattr__方法') # print(key, value) def __delattr__(self, item): # 这个方法在删除属性的时候会被触发 print('调用__delattr__方法') if item == 'age': pass else: super().__delattr__(item) t = Test() t.name = 'hh' print(t.name)
__delattr__