面向对象-描述符

描述符
如果一个类中包含了三个魔术方法(__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'

 

posted @ 2019-05-15 22:17  双伟科技  阅读(171)  评论(0编辑  收藏  举报