class Foo: x = 1 def __init__(self,y): self.y = y def __getattr__(self,item): print("---->from getattr:你找的属性不存在") def __setattr__(self,key,value): print('----> from setattr') # self.key = value # 这样就无限递归 # self.__dict__[key] = value #应该这样写 def __delattr__(self,item): print("---> from delattr") # del self.item # 上面的写法同样会无限递归 self.__dict__.pop(item) def __getitem__(self,item): print('---->from getitem') def __setitem__(self,item,value): print('---from setitem') def __delitem__(self,item): print('---->from __delitem__') # __setattr__:添加/修改属性就会触发它的执行 # 写的原理就是将属性和值写进对象的底层字典中,而我们重新写了 # __setattr__ 方法,所以不会写进去底层字典。 f1 = Foo(10) f1['y'] = 10 # 触发__setitem__ 方法 print(f1.__dict__) print(f1.__dict__) f1.z = 3 # # 触发__setattr__ print(f1.__dict__) # 除非是直接对底层字典进行操作,否则我们是永远无法赋值 f1.__dict__['z'] = 3 print(f1.z) # 3 # 此时f1 就有了z 属性 # __delattr__删除属性的时候会触发 f1.__dict__['a'] = 5 print(f1.__dict__) #{'z': 3, 'a': 5} del f1.a # 触发__delattr__方法 del f1['a'] # 触发__delitem__方法 print(f1.__dict__) # {'z': 3} # __getattr__ 只有在点调用属性且属性不存在的时候才会触发 f1.anc # 打印:---->from getattr:你找的属性不存在 f1['anc'] # 打印:---->from getitem:你找的属性不存在