面向对象-描述符
描述符:
如果一个类中包含了三个魔术方法(__get__,__set__,__delete__)之一或者全部的类这个类就是一个描述符
描述符的作用:
描述符的作用就是对类/对象中某个成员进行详细的管理操作。
数据描述符:(完整)
同时具备三个魔术方法的类就是数据描述符
非数据描述符(不完整):
没有同时具备三个魔术方法的类就是非数据描述符
描述符的第一种格式(推荐第一种格式)
三个魔术方法:
__get__():
触发时机:在访问对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:设置当前属性获取的值
参数:self 描述符的对象 / 第二个 管理成员的类的对象 / 第三个 管理成员的类
返回值:可有可无
注意事项:无
__set__():
触发时机:在设置对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:对成员的值进行设置管理
参数:self 描述符的对象 / 第二个 管理成员的类的对象 / 第三个 要设置的值
返回值:无
注意事项:设置值的时候一定要设置当前描述符对象的临时变量
__delete__():
触发时机:在删除对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:对成员的值进行删除管理
参数:self 描述符的对象 / 第二个 管理成员的类的对象
返回值:无
注意事项:删除值的时候一定要设置当前描述符对象的临时变量
1 #声明描述符类(道士) 2 class Descriptor: 3 #初始化一个临时的成员属性(代替原有uername的操作) 4 def __init__(self): 5 self.tmpvar = '匿名用户12345678'#道士手中的布娃娃 6 7 #定义描述符的三个成员 8 9 def __get__(self,obj,cls):#self 描述符的对象 / obj Email对象mail / cls Email类 10 11 #希望获取用户名的时候仅仅返回第一个字符 其余的都隐藏 12 result = self.tmpvar[0] + '*' + self.tmpvar[-1] 13 return result 14 15 def __set__(self,obj,val):#self 描述符的对象 / obj Email对象mail /val 要设置的值 16 #设置值的时候一定要设置当前描述符对象的临时变量 17 #限制用户名不能超过8个字符 18 #检测字符个数 19 if len(val) > 8: 20 self.tmpvar = val[0:8] 21 else: 22 self.tmpvar = val 23 24 def __delete__(self,obj):#self 描述符的对象/ obj Email对象mail 25 #删除临时变量即可 26 if obj.is_username == True: 27 del self.tmpvar 28 29 30 31 32 #声明一个类(邮箱) 33 class Email: 34 #成员属性 35 username = Descriptor()#用户名 交给描述符管理 [交接行为] 36 #设置一个是否允许删除username的标志 37 is_username = True 38 password = '123456' 39 phone = 1234567890 40 41 #成员方法 42 #登陆 43 def login(self): 44 print('这是登陆的方法') 45 46 #退出 47 def logout(self): 48 print('这是一个退出的方法') 49 50 #实例化对象 51 mail = Email() 52 #访问用户名 53 #print(mail.username) 54 #输出结果:匿*8 55 #设置用户名 56 #mail.username = 'lovemybaby' 57 #print(mail.username) 58 #输出结果:l*a 59 60 #删除用户名的操作 61 print(mail.username) 62 del mail.username 63 print(mail.username)
描述符和属性魔术方法:
属性魔术方法
__getattribute__
__getattr__
__setattr__
__delattr__
【针对当前类/对象所有成员的管理,属性魔术方法仅对当前类有效】
描述符(是一个类):
__get__
__set__
__delete__
【仅仅针对类/对象某一个成员的设置,描述符可对不同的类使用】
描述符的第二种格式:
描述符融合到被管理的成员类当中(使用了property函数)
1 ''' 2 #描述符类 3 #class Descriptor: 4 临时变量 自己定义 5 __get__ 管理获取值 6 __set__ 管理设置值 7 __delete__ 管理删除值 8 9 ''' 10 #声明一个邮箱类 11 class Email: 12 13 #成员属性 14 #username = '匿名用户' 15 isallowdel_username = False#是否允许删除的标志 16 password = 1235678 17 18 #成员方法 19 #------------描述符使用的区域 start-------------- 20 #初始化方法 21 def __init__(self): 22 self.tmpvar = '匿名用户' 23 24 25 #管理获取的描述符的方法 26 def getusername(self): #只有一个self 27 #设置相关管理 28 result = self.tmpvar[0] + '~' + self.tmpvar[-1] 29 return result 30 31 #管理描述符设置的方法 32 def setusername(self,val): 33 #管理设置操作 34 self.tmpvar = val + 'sama' 35 36 #管理描述符删除的方法 37 def deleteusername(self): 38 #管理删除操作 39 if self.isallowdel_username == True: 40 del self.tmpvar 41 42 # ------------描述符使用的区域 end-------------- 43 44 def login(self): 45 print('登陆邮箱的方法') 46 47 def logout(self): 48 print('退出邮箱的方法') 49 50 #将成员交接给描述符管理 51 username = property(getusername,setusername,deleteusername) 52 53 #在类外部实例化对象 54 mail = Email() 55 56 #获取用户名 57 print(mail.username) 58 #输出结果:匿~户 59 60 #设置用户名 61 mail.username = '王老五' 62 print(mail.username) 63 #输出结果:王~a 64 65 #删除用户名 66 print(mail.username) 67 #输出结果:王~a 68 del mail.username 69 print(mail.username) 70 #输出结果:王~a
描述符的第三种格式:
描述符融合到被管理的成员类当中(使用装饰器语法组合)
1 ''' 2 临时变量 自己定义 ok 3 __get__ 管理获取值 4 __set__ 管理设置值 5 __delete__ 管理删除值 6 7 8 ''' 9 #声明一个邮箱类 10 class Email: 11 #成员属性 12 #username = '匿名用户' #直接注释 13 password = 123570 14 15 #成员方法 16 def __init__(self): 17 18 self.tmpvar = '匿名用户' 19 20 @property #将用户名username交给描述符管理 【默认用作获取的方法】 21 def username(self): 22 #管理获取操作 23 result = self.tmpvar[0:3] 24 return result 25 26 @username.setter 27 def username(self,val):#用于设置的方法 28 #管理设置操作 29 self.tmpvar = val 30 31 @username.deleter 32 def username(self):#用于删除的方法 33 del self.tmpvar 34 35 36 37 def login(self): 38 print('登陆邮箱的方法') 39 40 def logout(self): 41 print('退出邮箱的方法') 42 43 44 #实例化对象 45 mail = Email() 46 #获取操作 47 print(mail.username) 48 #输出结果:匿名用 49 50 #设置操作 51 mail.username = '今生为你偷' 52 print(mail.username) 53 #输出结果:今生为 54 55 #删除操作 56 print(mail.username) 57 #输出结果:今生为 58 del mail.username 59 print(mail.username)#因为username对删除,访问不到,所以报错 60 #输出结果:AttributeError: 'Email' object has no attribute 'tmpvar'