回顾什么是装饰器:
装饰器定义:本质就是函数(高阶函数),功能是为其他函数(对象)添加新功能
一、类的装饰器基本实现原理如下:
1 def deco(cls):
2 print('类的装饰器=========》')
3 print('='*20)
4 return cls
5
6 @deco #====> Foo = deco(Foo)
7 class Foo:
8 pass
二、上述的简单装饰器是没有参数的,现在我们加上参数
1 def cls_decorator(**kwargs): #支持传入参数(属性和对应的值),字典形式
2 def deco(cls):
3 for key,val in kwargs.items():
4 setattr(cls,key,val) #给类设置对应的属性和值
5 return cls
6 return deco
7
8 @cls_decorator(name='Menawey',age=24,gender='male') # 1 运行cls_decorator(...),返回deco;2 @deco===> Peolple = deco(People)
9 #相当于给People类设置了name、age、gender属性
10 class People:
11 pass
12
13 print(People.__dict__) #查看被装饰过的类的属性字典
通过这样就可以动态的给不同的类在他实例化前增加属性
三、结合描述符
通过描述符和类的装饰器组合使用,可以完成很多功能,比如为类添加属性,并且可以限定属性的类型。
1 #描述符
2 class Desc:
3 def __init__(self,key,value_type):
4 self.key = key
5 self.value_type = value_type
6 def __get__(self, instance, owner):
7 return instance.__dict__[self.key]
8 def __set__(self, instance, value):
9 if not isinstance(value,self.value_type):
10 raise TypeError('%s 传入的类型不是 %s'%(self.key,self.value_type))
11 instance.__dict__[self.key] = value
12 def __delete__(self, instance):
13 instance.__dict__.pop(self.key)
14
15 #装饰器
16 def cls_decorator(**kwargs): #支持传入参数(属性和对应的值),字典形式
17 def deco(cls):
18 for key,val in kwargs.items(): #这里需要用到描述符对属性进行代理,但是val是指定的类型,所以要用Desc(key,val)来描述为对应的值
19 setattr(cls,key,Desc(key,val)) #给类设置对应的属性和值
20 return cls
21 return deco
22
23 @cls_decorator(name=str,age=int,gender=str,salary=float) #使用装饰器
24
25 #被装饰和描述的类
26 class People:
27 def __init__(self,name,age,gender,salary):
28 self.name = name
29 self.age = age
30 self.gender = gender
31 self.salary = salary
32
33 p1 = People('Menawey',24,'male',11.1) #因为gender属性指定的是sstr,但是TypeError: age 传入的类型不是 <class 'int'>
34 print(People.__dict__)