python 裝飾器 & 可同時接受有引數與無引數的裝飾器
阿新 • • 發佈:2018-11-26
昨天下午仔細學習了裝飾器的內容,算是比較明白了。標題的題目來源於這裡
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引數是自動加上去的,為被裝飾函式)