Python中的decorator是一種對python語法的轉換寫法,使用decorator可以更方便的對函式作修改,也可以提高程式的可讀性。但是decorator只是一種語法糖,使用decorator並不會對語法產生改變,只是讓程式寫法可以更加的簡潔,並且讓開發者可以更方便的使用。
下面開始來說明一下,如何使用decorator來實作在函式的修改:
假設我們寫了一個執行sql的函式:
1 2
| def select_execute(sql): return 'execute select sql query!'
|
如果我們想要對這個執行sql的函式,用一個debug模式來包起來,並在debug模式印出執行的sql與執行的時間,這時可以透過closure來處理函式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| def debug_query(func): def debug_execute(sql): exec_msg = func(sql) exec_time = datetime.now() debug_msg = """ Execute: {sql} Result: {exec_msg} Execute Time: {exec_time}""" return debug_msg.format(**locals()) return debug_execute >>> sql = 'SELECT * FROM TABLE' >>> select_execute(sql) execute select sql query!
>>> func = debug_query(select_execute) >>> func(sql) Execute: SELECT * FROM TABLE Result: execute select sql query! Execute Time: 2017-05-20 16:09:08.953792
|
從上面的範例可以看到,先將執行sql的函式傳入外部函式,並在內部函式捕捉後,加上debug要印的部份進行改寫,這樣就可以將執行sql的函式包裝成debug模式。下面是使用decorator的寫法
1 2 3 4 5 6 7 8
| @debug_query def select_execute(sql): return 'execute select sql query!'
>>> select_execute(sql) Execute: SELECT * FROM TABLE Result: execute select sql query! Execute Time: 2017-05-20 16:09:08.953792
|
只要透過@和改寫的函式名稱,就可以簡化函式傳遞的語法,讓程式碼可以更加簡潔並達到相同效果
decorator也可以支援帶參數,如果今天要簡單的多印出一行debug宣告,並指定是哪一種query type作說明,可以透過多加上一層outter函式來傳入參數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| def debug_describe(query_type): def debug_query(func): def debug_execute(sql): exec_msg = func(sql) exec_time = datetime.now() descirbe = 'It is {} debug mode'.format(query_type) debug_msg = """ {descirbe} Execute: {sql} Result: {exec_msg} Execute Time: {exec_time}""" return debug_msg.format(**locals()) return debug_execute return debug_query >>> func = debug_describe('select')(select_execute) >>> func(sql) It is select debug mode Execute: SELECT * FROM TABLEResult: execute select sql query! Execute Time: 2017-05-20 16:09:08.962798
@debug_describe('select') def select_execute(sql): return 'execute select sql query!' >>> select_execute(sql) Execute: SELECT * FROM TABLE Result: execute select sql query! Execute Time: 2017-05-20 16:09:08.962798
|
參考資料:
PythonDecorators
Understanding Decorators in Python
Python Decorator 四種寫法範例 Code