Python装饰器日志:函数是否被调用两次?能否优化日志逻辑?
问题解答
你的理解是否正确?
不正确。被装饰后的add实际上是装饰器返回的wrapper函数,当你调用add(2,3)时,执行的是wrapper逻辑,而wrapper内部的function(*args, **kwargs)才是调用原add函数的唯一一次。整个过程中原add函数只被调用了一次,不存在两次调用的情况。
你想要的功能是否可行?
不可行,核心原因如下:
- 如果不在装饰器中执行
function(*args, **kwargs),被装饰后的add只会输出日志,完全不会执行原函数的加法逻辑,违背了装饰器“增强原有功能而非替代功能”的本质。 - 异常记录必须依赖捕获原函数执行时抛出的异常,只有调用原函数才可能触发异常,因此必须在装饰器的
try-except块中执行原函数,才能捕获并记录错误。
如果只是想简化日志内容(比如不需要记录返回值),可以修改装饰器,保留你需要的核心功能:
from functools import wraps import logging 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: return function(*args, **kwargs) except Exception as error: logger.debug("Function '{}' raised {} with error '{}'" .format(function.__name__, error.__class__.__name__, str(error))) raise error return wrapper return wrap @logged() def add(a, b): return a + b
这段代码实现了你要求的两个功能:记录调用参数、异常时记录错误,同时会正确执行原函数逻辑,且不会重复调用原函数。
内容的提问来源于stack exchange,提问作者cryp
相关产品推荐
相关产品推荐

