無參的@log裝飾器:python
def log(f): def fn(x): print 'call ' + f.__name__ + '()...' return f(x) return fn
發現對於被裝飾的函數,log打印的語句是不能變的(除了函數名)。app
若是有的函數很是重要,但願打印出'[INFO] call xxx()...',有的函數不過重要,但願打印出'[DEBUG] call xxx()...',這時,log函數自己就須要傳入'INFO'或'DEBUG'這樣的參數,相似這樣:函數
@log('DEBUG') def my_func(): pass
把上面的定義翻譯成高階函數的調用,就是:翻譯
my_func = log('DEBUG')(my_func)
上面的語句看上去仍是比較繞,再展開一下:blog
log_decorator = log('DEBUG') my_func = log_decorator(my_func)
上面的語句又至關於:class
log_decorator = log('DEBUG') @log_decorator def my_func(): pass
因此,帶參數的log函數首先返回一個decorator函數,再讓這個decorator函數接收my_func並返回新函數:test
def log(prefix): def log_decorator(f): def wrapper(*args, **kw): print '[%s] %s()...' % (prefix, f.__name__) return f(*args, **kw) return wrapper return log_decorator @log('DEBUG') def test(): pass print test()
執行結果:call
[DEBUG] test()... None