注意:跟类无关,只对类的实例起作用
1.__getattr__
class Foo: def __init__(self,name): self.name=name # def __getattr__(self, item): # print('你找的属性%s不存在'%item) f1=Foo('alex') print(f1.name) #alex print(f1.age) #报错:AttributeError: 'Foo' object has no attribute 'age' #类Foo本身就有内置函数__getattr__,当在类中又定义了一个__getattr__时,则执行的是新定义的
当_get_getattr__与__getattribute__一起出现时:
当属性存在时,触发__getattribute__
当属性不存在时,也是先触发__getattribute__,然后通过语句:raise AttributeError 触发__getattr__
class Foo: def __init__(self,x): self.x=x def __getattr__(self, item): print('执行的是getattr') # return self.__dict__[item] # def __getattribute__(self, item): # print('执行的是getattribute') # raise AttributeError('抛出异常了') # raise TabError('xxxxxx') f1=Foo(10) # f1.x f1.xxxxxx #不存在的属性访问,触发__getattr__
2.__setattr__
# class Foo: # def __init__(self,name): # self.name=name # # def __setattr__(self, key, value): # print('执行__setattr__') # # f1=Foo('alex') # 执行__setattr__ # print(f1.__dict__) #{} # #执行了自己定义的__setattr__,并不会真正往字典属性里传值 #要求:往字典属性里传值,值必须是str类型 class Foo: def __init__(self,name): self.name=name def __setattr__(self, key, value): print('执行__setattr__') if type(value) is str: print('开始设置属性') # self.key=value #又触发__setattr__ self.__dict__[key]=value else: print('必须是字符串类型') f1=Foo('alex') # 执行__setattr__ f1.age=18 print(f1.__dict__) #{}
3.__delattr__
class Foo: def __init__(self,name): self.name=name def __delattr__(self, item): print('执行__delattr__') # f1.__dict__.pop(item) #这样才会真正的删除 f1=Foo('alex') f1.age=18 print(f1.__dict__) #{'name': 'alex', 'age': 18} del f1.age #执行__delattr__ print(f1.__dict__) #{'name': 'alex', 'age': 18}