Python进阶-----类的装饰器及应用

回顾什么是装饰器:
  装饰器定义:本质就是函数(高阶函数),功能是为其他函数(对象)添加新功能

一、类的装饰器基本实现原理如下:

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__)

 

posted @ 2018-11-03 20:33  Meanwey  阅读(3059)  评论(0编辑  收藏  举报