面向对象-魔术方法-属性相关
属性相关的魔术方法:
就是获取成员,删除成员,修改成员相关联的魔术方法而已
5个与属性相关的魔术方法
1.__getattr__
2.__setattr__
3.__delattr__
4.__getattribute__
5.__dir__
属性访问的顺序!
1.调用__getattribute__
2.【调用数据描述符】
3.调用当前对象的所属成员
4.调用类的所属成员
5.【调用非数据描述符】
6.调用父类的所属成员
7.调用__getattr__
注意:以上步骤是调用某个成员的访问顺序及优先级。前面的能获取成员,就不会向后查找
1.__getattribute__
触发时机:访问对象成员的时候就会触发,无论成员是否存在
作用:可以在用户获取数据的时候进行数据处理等操作
参数:一个self接受当前对象,另外一个参数接受访问对象成员名称的字符串
返回值:有 不设定返回None
注意事项:在当前魔术方法中禁止使用 当前对象.成员 的方式访问成员,会触发递归操作,必须借助object的__getattribute__来获取当前对象的成员
1 #__getattribute__属性魔术方法 2 class Human: 3 #添加成员属性(离开入对象) 4 def __init__(self): 5 self.name ='里斯' 6 self.sex = "男" 7 self.age = 18 8 9 #添加魔术方法 10 def __getattribute__(self,item): 11 print("getattribute方法被触发") 12 13 #如果用当前 self.item 获取的话就回触发自已,导致最大深度的递归错误 14 #所以用最顶层的 object.__getattribute(self,item)来获取 15 #item参数可以是任意变量,item参数就是获取,对象.属性-item实参 16 var = object.__getattribute__(self,item) 17 var2 = var[0] + '*' + var[-1] 18 return var2 19 20 #添加成员方法 21 def eat(self): 22 print('一天三次小烧烤') 23 24 def drink(self): 25 print('喝啤酒') 26 27 #实例化对象 28 ls = Human() 29 #打印对象 30 print(ls) 31 32 #打印对象的属性,触发__getattribute__的方法存 33 #print(ls.name2) 34 #输出结果:AttributeError: 'Human' object has no attribute 'name2' 35 36 print(ls.name) 37 ''' 38 输出结果: 39 getattribute方法被触发 40 里*斯 41 '''
2.__getattr__
触发时机:访问不存在的对象成员的时候自动触发
作用:防止访问不存在成员的时候报错!为不存在的成员定义值
参数:一个self接受当前对象,第二个参数接受访问成员的名称字符串
返回值:可有可无
注意事项:无
1 #__getattr__属性魔术方法 2 class Human: 3 #添加成员属性(离开入对象) 4 def __init__(self): 5 self.name ='里斯' 6 self.sex = "男" 7 self.age = 18 8 self.err = '没有这个名字' 9 10 #__getattr__访问不存在的属性时触发, 11 def __getattr__(self,item): #item参数可以是任意变量,item参数就是获取,对象.属性-item实参 12 print('getattr被触发') 13 item = self.err 14 return item 15 #添加成员方法 16 def eat(self): 17 print('一天三次小烧烤') 18 19 def drink(self): 20 print('喝啤酒') 21 22 #实例化对象 23 ls = Human() 24 #打印对象 25 print(ls) 26 #输出结果:<__main__.Human object at 0x000001DA5A292BE0> 27 28 print(ls.name2) 29 ''' 30 输出结果: 31 getattr被触发 32 没有这个名字 33 '''
3.__setattr__
触发时机:添加对象成员或者修改对象成员的时候自动触发!
作用:可以限制或者管理对象成员的添加与修改操作
参数:一个self接受当前对象 第二个接受设置的成员名称字符串 第三个设置的值
返回值:无
注意事项:在当前魔术方法中禁止使用当前对象.成员名 = 值的方式,会触发递归cao'zuo !
1 #__setattr__属性魔术方法 2 class Human: 3 #sex属在在类设置,因为一但触发__setattr__修改属性方法,就会被清空,连添加都不可以 4 #所在sex在类设置就不会被清空 5 sex = "男" 6 #添加成员属性(离开入对象) 7 def __init__(self): 8 self.name ='里斯' 9 10 self.age = 18 11 self.err = '没有这个名字' 12 13 #__setattr__访问不存在的属性时触发, 14 def __setattr__(self,a,b):#须要在self,后面添加两个参数 a = 成员属性(例:name),b = 修改后的值 15 #1.相当于在重载object的__setattr__,如第2项重载回object的操作相当恢复默认 16 # 2.object.__setattr__(self,a,b) 17 #print('setattr被触发' + str(a) + str(b)) 18 19 #1.禁止修改性别,1.修改名称最多使用三个字符多余的舍弃 20 if a == 'sex': 21 pass 22 else: 23 object.__setattr__(self,a,b) 24 25 #添加成员方法 26 def eat(self): 27 print('一天三次小烧烤') 28 29 def drink(self): 30 print('喝啤酒') 31 32 #实例化对象 33 ls = Human() 34 #打印对象 35 print(ls) 36 #输出结果:<__main__.Human object at 0x0000023932572BE0> 37 38 print(ls.__dict__) 39 #输出结果:{'name': '里斯', 'age': 18, 'err': '没有这个名字'} 40 ls.name = '老里' 41 print(ls.__dict__) 42 #输出结果:{'name': '老里', 'age': 18, 'err': '没有这个名字'} 43 44 print(ls.sex) 45 #输出结果:男 46 ls.sex = '女' #被__setattr__设置禁止修改性别 47 print(ls.sex) 48 #输出结果:男 49 50 #没有设置__setattr__方法的修改成员属性及输出如下 51 #print(ls.__dict__) 52 #输出结果:{'name': '里斯', 'sex': '男', 'age': 18, 'err': '没有这个名字'} 53 #ls.name = '老里' 54 #print(ls.__dict__) 55 #输出结果:{'name': '老里', 'sex': '男', 'age': 18, 'err': '没有这个名字'}
4.__delattr__
触发时机:删除对象成员的时候自动触发
作用:可以限制对象成员的删除
参数:一个self接受当前对象,另外一个接受删除的成员属性名称的字符串
返回值:无
注意事项:如果要删除对象成员,要借助object中的__delattr__来操作。
5.__dir__
触发时机:使用dir函数操作对象的时候自动触发
作用:
参数:一个self接受当前对象
返回值:有,必须是容器类数据
注意事项: