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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM