廖雪峰python摘錄5
阿新 • • 發佈:2017-09-03
新的 aps ret col 出錯 簽名 一個 復制 div
1、假設我們要增強now()
函數的功能,比如,在函數調用前後自動打印日誌,但又不希望修改now()
函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。
2、由於log()
是一個decorator,返回一個函數,所以,原來的now()
函數仍然存在,只是現在同名的now
變量指向了新的函數,於是調用now()
將執行新函數,即在log()
函數中返回的wrapper()
函數。
3、wrapper()
函數的參數定義是(*args, **kw)
,因此,wrapper()
函數可以接受任意參數的調用。在wrapper()
函數內,首先打印日誌,再緊接著調用原始函數。
4、
因為返回的那個wrapper()
函數名字就是‘wrapper‘
,所以,需要把原始函數的__name__
等屬性復制到wrapper()
函數中,否則,有些依賴函數簽名的代碼執行就會出錯。
不需要編寫wrapper.__name__ = func.__name__
這樣的代碼,Python內置的functools.wraps
就是幹這個事的,所以,一個完整的decorator的寫法如下:
1 import functools 2 3 def log(text): 4 def decorator(func): 5 @functools.wraps(func) 6 defwrapper(*args, **kw): 7 print(‘%s %s():‘ % (text, func.__name__)) 8 return func(*args, **kw) 9 return wrapper 10 return decorator
廖雪峰python摘錄5