我正在嘗試通過裝飾器記錄期望??并遇到了一個代碼片段(見下文)
from functools import wraps
def logged(log='trace'):
def wrap(function):
@wraps(function)
def wrapper(*args, **kwargs):
logger = logging.getLogger(log)
logger.debug("Calling function '{}' with args={} kwargs={}"
.format(function.__name__, args, kwargs))
try:
response = function(*args, **kwargs)
except Exception as error:
logger.debug("Function '{}' raised {} with error '{}'"
.format(function.__name__,
error.__class__.__name__,
str(error)))
raise error
logger.debug("Function '{}' returned {}"
.format(function.__name__,
response))
return response
return wrapper
return wrap
@logged()
def add(a, b):
return a b
代碼作業正常,但如果我呼叫 add(2,3) 似乎 add 函式被呼叫兩次,一次在裝飾器內(添加值存盤在回應變數中),然后當我實際呼叫 add(2,3) 時我的代碼。
我的理解正確嗎?如果是這樣,我理想情況下希望裝飾器只執行以下操作:
- 使用 args 列印“呼叫函式”
- 如果在我呼叫 add(2,3) 時發生例外,請記錄錯誤。這應該在沒有
response = function(*args, **kwargs)在裝飾器中做的情況下發生
那可能嗎 ?
uj5u.com熱心網友回復:
似乎 add 函式被呼叫了兩次 [...] 我的理解正確嗎?
不,您需要了解裝飾器只不過是函式的語法糖,該函式(通常)將可呼叫物件(即函式)作為引數并回傳可呼叫/函式。
在這種情況下,有幾層嵌套,但最終,在解釋器到達裝飾函式定義的末尾之后,您所擁有的是wrapper偽裝成函式的內部add函式。
當您稍后呼叫時,該包裝器就是所謂的add(2, 3)。并且根據它的定義,它將依次呼叫“實際” add,wrapper作為 的引數傳遞給function的定義wrap。
在此之前,沒有呼叫“實際”添加,因為沒有呼叫包裝器。add僅作為可呼叫傳遞給內部裝飾器并用于構造wrapper函式。然后wrapper在裝飾后將功能回傳給您。
這應該在沒有
response = function(*args, **kwargs)在裝飾器中做的情況下發生
如果你不在function那里呼叫,實際的函式(在這種情況下add)將永遠不會被呼叫。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/512976.html
標籤:Python例外装饰师
上一篇:確定例外原因
下一篇:c中的strcpy訪問沖突
