自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

搞定三大神器之 Python 裝飾器

開發(fā) 后端
裝飾器,幾乎各大Python框架中都能看到它的身影,足以表明它的價值!它有動態(tài)改變函數(shù)或類功能的魔力!

裝飾器,幾乎各大Python框架中都能看到它的身影,足以表明它的價值!它有動態(tài)改變函數(shù)或類功能的魔力!

[[344466]]

1. 什么是裝飾器

對于受到封裝的原函數(shù)比如f來說,裝飾器能夠在f函數(shù)執(zhí)行前或者執(zhí)行后分別運行一些代碼。

2. 裝飾器的結(jié)構(gòu)

裝飾器也是一個函數(shù),它裝飾原函數(shù)f或類cls后,再返回一個函數(shù)g

裝飾一個函數(shù):

  1. def decorator(f): 
  2.   # 定義要返回的函數(shù) 
  3.   def g(): 
  4.     print('函數(shù)f執(zhí)行前的動作') 
  5.     f() 
  6.     print('函數(shù)f執(zhí)行后的動作') 
  7.   return g 

裝飾一個類:

  1. def decorator(cls): 
  2.   # 定義要返回的函數(shù) 
  3.   def g(): 
  4.     print('類cls執(zhí)行前的動作') 
  5.     f() 
  6.     print('類cls執(zhí)行后的動作') 
  7.   return g 

使用裝飾器很簡單,@+自定義裝飾器 裝飾要想裝飾的函數(shù)。

3. 為什么要這樣

要想理解裝飾器為什么要有這種結(jié)構(gòu),要首先想明白裝飾器的目標是什么。

它的價值在于為原函數(shù)f增加一些行為,前提必須不能破壞函數(shù)f,所以肯定不能改變f的內(nèi)部結(jié)構(gòu),所以只能在調(diào)用f前后定義一些行為。

同時,裝飾器函數(shù)decorator返回值又是什么?你可以思考下,返回一個函數(shù)是再好不過的了,它包裝了原函數(shù)f.

4. 裝飾一個函數(shù)

printStar函數(shù)接收一個函數(shù)f,返回值也是一個函數(shù),所以滿足裝飾器的結(jié)構(gòu)要求,所以printStar是一個裝飾器。

  1. def printStar(f): 
  2.     def g(): 
  3.         print('*'*20) 
  4.         f() 
  5.         print('*'*20) 
  6.     return g 

printStar裝飾器實現(xiàn)f函數(shù)執(zhí)行前、后各打印20個*字符。

使用printStar:

  1. @printStar 
  2. def f(): 
  3.     print('hello world') 

調(diào)用:

  1. if __name__ == '__main__': 
  2.    ### 改變函數(shù)功能 
  3.    f() 

打印結(jié)果:

  1. ******************** 
  2. hello world 
  3. ******************** 

可以很方便的裝飾要想裝飾的其他函數(shù),如下:

  1. @printStar 
  2. def g(): 
  3.     print('welcome to Python') 

5. 裝飾一個類

除了可以裝飾函數(shù)f外,還可以裝飾類cls,兩者原理都是一樣的。

下面給出一個裝飾器實現(xiàn)單例模式的例子,所謂單例就是類只有唯一實例,不能有第二個。

  1. def singleton(cls): 
  2.    instance = {} 
  3.  
  4.    def get_instance(*args, **kwargs): 
  5.        if cls not in instance: 
  6.            instance[cls] = cls(*args, **kwargs) 
  7.        return instance[cls] 
  8.    return get_instance 

定義字典instance,鍵值對分別為類和實例,這樣確保只cls()一次。

使用裝飾器singleton修飾類:

  1. @singleton 
  2. class CorePoint: 
  3.    pass 

測試:

  1. if __name__ == '__main__': 
  2.    ### 改變類的功能 
  3.    c1 = CorePoint() 
  4.    c2 = CorePoint() 
  5.    print(c1 is c2) # True 

6. 裝飾器層疊

上面原函數(shù)f不僅能被一個裝飾器修飾,還能被n多個裝飾器修飾。

下面再定義一個裝飾器printLine,被修飾函數(shù)執(zhí)行前后打印20個:

  1. def printLine(f): 
  2.     def g(): 
  3.         print('-'*20) 
  4.         f() 
  5.         print('-'*20) 
  6.     return g 

使用上文定義好的printStar和printLine同時裝飾函數(shù)f:

  1. @printStar 
  2. @printLine 
  3. def f(): 
  4.     print('hello world') 

此時再調(diào)用函數(shù)f:

  1. if __name__ == '__main__': 
  2.    ### 改變函數(shù)功能 
  3.    f() 

打印結(jié)果:

  1. ******************** 
  2. -------------------- 
  3. hello world 
  4. -------------------- 
  5. ******************** 

f被裝飾后,先打印*,再打印 -

層疊多一層,原函數(shù)f就變強大一層。使用裝飾器,還能實現(xiàn)功能抽離,進一步實現(xiàn)松耦合。

7. 溫馨提醒

打印原函數(shù)f的名字__name__,結(jié)果為f

  1. In [1]: def f():  
  2.    ...:     pass  
  3.  
  4. In [4]: f.__name__                                                               
  5. Out[4]: 'f' 

但是,被裝飾后函數(shù)名字f變?yōu)間,這不是我們希望的!

  1. @printStar 
  2. def f(): 
  3.   pass 
  4.  
  5. f() 
  6. f.__name__ # g 

Python提供的解決方案:使用functools模塊中的wraps裝飾器:

  1. from functools import wraps 
  2.  
  3. def printStar(f): 
  4.     @wraps(f) 
  5.     def g(): 
  6.         print('*'*20) 
  7.         f() 
  8.         print('*'*20) 
  9.     return g 

此時再打印被裝飾后f的名字,顯示f,正常!

 

責任編輯:趙寧寧 來源: Python與算法社區(qū)
相關(guān)推薦

2018-06-08 10:18:22

Python裝飾器迭代器

2022-11-27 08:12:11

RocketMQ源碼工具類

2016-09-13 19:21:07

CTO管理技術(shù)

2023-12-13 13:28:16

裝飾器模式Python設(shè)計模式

2023-12-06 07:36:27

前端開發(fā)

2021-09-13 09:28:10

PuppeteerNode 庫DevTools 協(xié)議

2021-05-27 12:10:42

前端puppeteer代碼

2021-01-31 20:51:55

PuppeteerNode核心

2010-02-01 17:50:32

Python裝飾器

2010-06-04 09:08:56

2023-02-07 07:47:52

Python裝飾器函數(shù)

2021-03-23 09:06:34

下載神器文件下載插件

2023-09-04 13:14:00

裝飾器設(shè)計模式

2019-07-01 08:46:37

AI 數(shù)據(jù)人工智能

2023-05-05 07:12:09

GPT產(chǎn)品主題

2017-01-05 14:01:38

linux密碼高強度

2012-02-08 13:52:30

云計算

2016-11-01 09:24:38

Python裝飾器

2024-05-06 08:56:31

PythonHTML正則表達式

2022-09-19 23:04:08

Python裝飾器語言
點贊
收藏

51CTO技術(shù)棧公眾號