__getattr__:
属性查找失败后,解释器会调用 __getattr__ 方法.class TmpTest: def __init__(self): self.tmp = 'tmp123' def __getattr__(self, item): raise AttributeError('{} object has no attribute {}'.format(type(self), item))a=TmpTest()print(a.tmp)结果: tmp123print(a.tmpnone)结果: Traceback (most recent call last): File "D:/pythonScript/leetcode/leetcode.py", line 12, inprint(a.tmpnone) File "D:/pythonScript/leetcode/leetcode.py", line 7, in __getattr__ raise AttributeError(msg.format(tmp_cls, item)) AttributeError: object has no attribute tmpnone
a.tmpnone 表达式执行顺序:
1、首先会检查a实例有没有名为tmpnone的属性 2、到类(a.__class__)中查找 3、顺着继承树继续查找. 4、调用a所属类中定义的 __getattr__ 方法,传入self和属性名称的字符串形式(如 'tmpnone'). __getattribute__: 1、尝试获取指定的属性时总会调用这个方法,寻找的属性是特殊属性或特殊方法时除外. 2、点号与 getattr 和 hasattr 内置函数会触发这个方法. 3、调用 __getattribute__ 方法且抛出 AttributeError 异常时,才会调用 __getattr__ 方法. 4、为了在获取实例的属性时不导致无限递归,__getattribute__ 方法的实现要使用 super().__getattribute__(name)class TmpTest: def __getattr__(self, item): print("getting __getattr__ {}".format(item)) self.__dict__[item] = '__getattr__' return '__getattr__' def __getattribute__(self, item): print ("getting __getattribute__ {}".format(item)) if item=='x': raise AttributeError return object.__getattribute__(self, item) def __setattr__(self, key, value): print("getting __setattr__ {}".format(key)) return object.__setattr__(self, key, value)a=TmpTest()a.x='getattr'print (a.x)结果:getting __setattr__ x getting __getattribute__ x #抛出异常getting __getattr__ x #执行__getattr__getting __getattribute__ __dict__ __getattr__
def __delattr__(self, item): print ("getting __delattr__ {}".format(item)) del self.__dict__[item]
>>> import struct >>> dir() # show the names in the module namespace ['__builtins__', '__name__', 'struct'] >>> dir(struct) # show the names in the struct module ['Struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from'] >>> class Shape: ... def __dir__(self): ... return ['area', 'perimeter', 'location'] >>> s = Shape() >>> dir(s) ['area', 'location', 'perimeter']