編寫帶參數decorator

無參的@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
相關文章
相關標籤/搜索