描述符

如果一个类中包含了三个魔术方法(__get__,__set__,__delete__)之一或者全部的类这个类就是一个描述符

描述符的作用就是对类/对象中某个成员进行详细的管理操作。

同时具备三个魔术方法的类就是数据描述符。

没有同时具备三个魔术方法的类就是非数据描述符。

三个魔术方法

__get__()

触发时机:在访问对象成员属性(该成员已经交给描述符管理的时候)的时候触发

作用:设置当前属性获取的值

参数:self 描述符的对象 / 第二个 管理成员的类的对象 / 第三个 管理成员的类

返回值:可有可无

注意事项:无

__set__()

触发时机:在设置对象成员属性(该成员已经交给描述符管理的时候)的时候触发

作用:对成员的值进行设置管理

参数:self 描述符的对象 / 第二个 管理成员的类的对象 / 第三个 要设置的值

返回值:无

注意事项:设置值的时候一定要设置当前描述符对象的临时变量

__delete__()

触发时机:在删除对象成员属性(该成员已经交给描述符管理的时候)的时候触发

作用:对成员的值进行删除管理

参数:self 描述符的对象 / 第二个 管理成员的类的对象

返回值:无

注意事项:删除值的时候一定要设置当前描述符对象的临时变量

属性魔术方法:【针对当前类/对象所有成员的管理,属性魔术方法仅对当前类有效】

描述符(是一个类):【仅仅针对类/对象某一个成员的设置,描述符可对不同的类使用】

描述符的第一种格式

1
2
描述符的类
被管理的成员的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  #声明描述符类(道士)
class Descriptor:
#初始化一个临时的成员属性(代替原有uername的操作)
def __init__(self):
self.tmpvar = '匿名用户'#道士手中的布娃娃

#定义描述符的三个成员
def __get__(self,obj,cls):#self 描述符的对象 / obj Email对象mail / cls Email类
#希望获取用户名的时候仅仅返回第一个字符 其余的都隐藏
result = self.tmpvar[0] + '*' + self.tmpvar[-1]
return result

def __set__(self,obj,val):#self 描述符的对象 / obj Email对象mail /val 要设置的值
#设置值的时候一定要设置当前描述符对象的临时变量
#限制用户名不能超过8个字符
#检测字符个数
if len(val) > 8:
self.tmpvar = val[0:8]
else:
self.tmpvar = val

def __delete__(self,obj):#self 描述符的对象/ obj Email对象mail
#删除临时变量即可
if obj.isallowdel_username == True:
del self.tmpvar

#声明一个类(邮箱)
class Email:
#成员属性
username = Descriptor()#用户名 交给描述符管理 [交接行为]
#设置一个是否允许删除username的标志
isallowdel_username = True
password = '123456'
phone = 1234567890

#成员方法
#登陆
def login(self):
print('这是登陆的方法')
#退出
def logout(self):
print('这是一个退出的方法')

#实例化对象
mail = Email()
#访问用户名
print(mail.username)
#设置用户名
mail.username = 'lovemybaby'
#删除用户名的操作
print(mail.username)
del mail.username
print(mail.username)

描述符的第二种格式

描述符融合到被管理的成员类当中(使用了property函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#声明一个邮箱类
class Email:
#成员属性
#username = '匿名用户'
isallowdel_username = False#是否允许删除的标志
password = 1235678

#成员方法
#------------描述符使用的区域 start--------------
#初始化方法
def __init__(self):
self.tmpvar = '匿名用户'
#管理获取的描述符的方法
def getusername(self): #只有一个self
#设置相关管理
result = self.tmpvar[0] + '~' + self.tmpvar[-1]
return result
#管理描述符设置的方法
def setusername(self,val):
#管理设置操作
self.tmpvar = val + 'sama'
#管理描述符删除的方法
def deleteusername(self):
#管理删除操作
if self.isallowdel_username == True:
del self.tmpvar
# ------------描述符使用的区域 end--------------

def login(self):
print('登陆邮箱的方法')
def logout(self):
print('退出邮箱的方法')

#将成员交接给描述符管理
username = property(getusername,setusername,deleteusername)

#在类外部实例化对象
mail = Email()
#获取用户名
#print(mail.username)
#设置用户名
#mail.username = '王老五'
#print(mail.username)
#删除用户名
print(mail.username)
del mail.username
print(mail.username)

描述符的第三种格式

描述符融合到被管理的成员类当中(使用装饰器语法组合)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#声明一个邮箱类
class Email:
#成员属性
#username = '匿名用户' #直接注释
password = 123570

#成员方法
def __init__(self):
self.tmpvar = '匿名用户'

@property #将用户名username交给描述符管理 【默认用作获取的方法】
def username(self):
#管理获取操作
result = self.tmpvar[0:3]
return result

@username.setter
def username(self,val):#用于设置的方法
#管理设置操作
self.tmpvar = val

@username.deleter
def username(self):#用于删除的方法
del self.tmpvar

def login(self):
print('登陆邮箱的方法')

def logout(self):
print('退出邮箱的方法')

#实例化对象
mail = Email()
#获取操作
#print(mail.username)
#设置操作
#mail.username = '今生为你偷'
#print(mail.username)
#删除操作
print(mail.username)
del mail.username