Python Decorator
Why Decorator
試想一個場景,如何在不變動下述程式片段的情況下,在進入Function時,印出Function名稱?
Simple Decorator
利用Python的Functional programming特性,將要裝飾(Decorate)的Function作爲另一個Function參數,來達成上述目的
print_function_name function就是一個簡單的裝飾器。其實就是一個接收一個Function形態的參數,而且返回的也是一個Function。
上述說明與程式變量的對應:
- Function形態的參數: func
- 返回的也是一個Function: wrapper
Syntax sugar @
利用Syntax sugar @ 可以達成相同效果且更爲簡潔的語法
Applications
透過上述可知裝飾器(Decorator)有下述的應用場景:
- 在程式運行期間動態增加Function的功能,而且不能影響目標Function的場景
- 要重覆使用某些程式片段的場景
而上述就是AOP(Aspect Oriented Program)的要解決的場景之一。常見的應用場景爲日誌插入、權限校驗等
Decorator Description
- 本質上是Python的Function或Class
- 是閉包(Closure)的一種
- 接收一個Function形態的參數
- 返回一個Function形態的物件,該Function會對接收的Function進行包裝或操作
- 接收的Function可以是Generator,達成與Decorator交互執行目的
Decorator Execution Order
基於Syntax sugar的版本新增一些Log,觀察整個調用順序
此時再新增一個調用Decorator的Function,顯示的調用順序爲
一個Function使用多個Decorator的調用順序爲
上述執行順序大致等於下述寫法
Kinds of Decorator
除了上述最簡單的Decorator,下面舉出幾個進階的Decorator
Decorators caller with arguments
- 當Decorators caller需要參數傳入
- 將傳入的參數同時附加在返回的Function,達成參數傳遞目的
|
|
Decorators with arguments
- 當Decorators本身需要參數傳入
- 需要多一層的Outter function來接收參數傳入
- 一層一層的返回function
|
|
Decorators on classe functions
- Python built-in提供了一些關於這類的Class,例如@classmethod,@staticmethod,和@property
- 第二層function需要接收self參數,故使用args來達成目的
|
|
Classes as decorators
- 實作一個Class作爲Decorator,並作用於Function
- Decorator class需要實作__call__ function
- Decorator caller會在__init__傳入,Decorator需要將它存儲
- __call__接收*args與**kwargs參數,可以完成caller的參數傳遞
|
|
Classes as Decorators with Arguments
- 當實作可接收參數的Decorator class時,Decorator caller本身會在__call__被傳入,與沒有接收參數的Decorator class不同
- wrapper接收*args與**kwargs參數,可以完成caller的參數傳遞
|
|