Python進階: 通過例項詳解裝飾器(附程式碼)
阿新 • • 發佈:2021-09-28
Python中的裝飾器有很多用處,比如輸出日誌、引數檢查、代理設定、計數計時、結果快取等等。本文就通過幾個裝飾器例子,詳細解釋一下Python中裝飾器的用法。
- 一步步從簡到繁學習裝飾器用法
- 其他一些裝飾器例項
- Python中自帶的裝飾器
按照慣例,先上程式碼:GitHub - xianhu/LearnPython: 以擼程式碼的形式學習Python
一步步從簡到繁學習裝飾器用法
(1)最簡單的裝飾器,實現日誌輸出功能:
# 構建裝飾器
def logging(func):
@functools.wraps(func)
def decorator():
print("%s called" % func.__name__)
result = func()
print("%s end" % func.__name__)
return result
return decorator
# 使用裝飾器
@logging
def test01():
return 1
# 測試用例
print(test01())
print(test01.__name__)
程式碼很簡單,很容易看懂。這裡注意"functools.wraps"用法,其目的是"test01.__name__"輸出正確的"test01"。"@logging"相當於"test01 = logging(test01)",返回的是decorator函式,所以如果不加"functools.wraps",則"test01.__name__"返回為"decorator"。
注意,此時test01沒有引數,對於帶有引數的函式,logging裝飾器則不再適用。那麼如果想裝飾帶有引數的函式,裝飾器該怎麼寫呢?
(2)裝飾器傳入函式引數,並正確返回結果:
# 構建裝飾器
def logging(func):
@functools.wraps(func)
def decorator(a, b):
print("%s called" % func.__name__)
result = func(a, b)
print("%s end" % func.__name__)
return result
return decorator
# 使用裝飾器
@logging
def test01(a, b):
print("in function test01, a=%s, b=%s" % (a, b))
return 1
# 測試用例
print(test01(1, 2))
這裡的test01函式帶有引數a、b,那麼decorator函式帶有同樣的引數即可。那麼問題又來了,如何讓logging裝飾器更加通用,而不是隻裝飾引數為兩個的函式呢?這時候自然想到Python中的 * 和 ** 的用法。
# 構建裝飾器
def logging(func):
@functools.wraps(func)
def decorator(*args, **kwargs):
print("%s called" % func.__name__)
result = func(*args, **kwargs)
print("%s end" % func.__name__)
return result
return decorator
# 使用裝飾器
@logging
def test01(a, b):
print("in function test01, a=%s, b=%s" % (a, b))
return 1
# 使用裝飾器
@logging
def test02(a, b, c=1):
print("in function test02, a=%s, b=%s, c=%s" % (a, b, c))
return 1
# 測試用例
print(test01(1, 2))
print(test02(1, 2, c=3, d=