>>> def log(func):
... def wrapper(*args, **kwargs):
... print "call: ", func.__name__
... return func(*args, **kwargs)
... return wrapper
...
>>> @log
... def now():
... print "It's now..."
...
>>> now()
call: now
It's now...
>>> def log(func):
... print "call: ", func.__name__
... return func
...
>>> @log
... def now():
... print "It's now......"
...
call: now
>>> now()
It's now......
裝飾器函數的第一層用於接收被裝飾函數的函數本身,第二層用於接收被裝飾函數時,傳遞的參數。關於這個,我寫過一篇blog
http://coolbit.in/blog/2014/03/29/decorator-exception-handling/
只要你能理解下列程式碼:
與
完全一樣,一切問題就可以用很容易的方式來解釋了。
為什麼會有一個 wrapper 函式來將程式碼包一層?
這是為了接收 now 函數的參數。
既然
now = log(now)
那就要求 log 的回傳值必須是個函數。當你呼叫now(*args)
的時候就必須要保證 log 回傳的函數能夠接收到 *args 參數。這下你明白了吧。我覺得裝飾器可以看做是閉包的一種特殊形式
至少要有閉包才能算真正的裝飾器