1. 程式人生 > >python 裝飾器 & 可同時接受有引數與無引數的裝飾器

python 裝飾器 & 可同時接受有引數與無引數的裝飾器

昨天下午仔細學習了裝飾器的內容,算是比較明白了。標題的題目來源於這裡

from functools import wraps
def log(ft):
    if not isinstance(ft, str):
        @wraps(ft)
        def wrapper(*args, **kwargs):
            print('wrapper')
            return ft(*args, **kwargs)
        return wrapper
    else:
        def decorator(func)
: @wraps(func) def wrapper(*args, **kwargs): print('wrapper and text:{}'.format(ft)) return func(*args, **kwargs) return wrapper return decorator # 測試結果: In [2]: @log ...: def test(): ...: print('test') ...: In [
3]: test() wrapper test In [4]: @log('execute') ...: def test(): ...: print('test') ...: In [5]: test() wrapper and text:execute test

裝飾器: 裝飾器本身是一個函式,然後接受另外一個函式作為引數,在返回被裝飾函式的執行結果的前後可以做些事情。比如:

from functools import wraps
def log(func):
    @wraps(func)# wraps 的作用是處理裝飾之後函式的__name__屬性的改變
def wrapper(*args, **kwargs): print('wrapper') # 在被裝飾函式執行之前列印一些資訊 return func(*args, **kwargs) # 原樣返回原函式的返回值,引數不變 return wrapper # 當裝飾發生的時候,相當於 test = log(test) # 如果裝飾器本身需要接受引數的話, 相當於 test = log(args)(test), 所以在log這個裝飾器內部需要返回一個類似不接受引數的裝飾器,然後這個不需要接受引數的裝飾器可以使用外部的引數,相當於閉包。 def log(text): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): print('wrapper and text:{}'.format(text)) # 可以使用text變數,相當於閉包 return func(*args, **kwargs) return wrapper return decorator # 返回一個相當於上面的不需要接受引數的裝飾器(func引數是自動加上去的,為被裝飾函式)