回顧什么是裝飾器:
裝飾器定義:本質就是函數(高階函數),功能是為其他函數(對象)添加新功能
一、類的裝飾器基本實現原理如下:
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__)