如何修改Python装饰器代码以生成符合预期的函数调用日志?
修正装饰器日志输出以匹配预期格式
问题说明
需要实现一个装饰器,记录被装饰函数的调用名称、带参数名的位置参数、关键字参数及执行时间并写入日志文件,现有代码输出格式与预期不符,需调整。
现有装饰器代码
from time import time def log(func): def wrapper(*args, **kwargs): start_time = time() func(*args, **kwargs) end_time = time() - start_time with open('log.txt', 'a+') as file: file.write(f'{func.__name__}; args: {args}, kwargs: {kwargs}, execution time: {end_time}\n sec.') return wrapper
测试代码
@log def foo(a, b, c): ... foo(1, 2, c=3)
输出对比
预期输出
foo; args: a=1, b=2; kwargs: c=3; execution time: 0.12 sec.
实际输出
foo; args: (1, 2), kwargs: {'c': 3}, execution time: 0.0 sec.
修改后的代码
from time import time import inspect def log(func): def wrapper(*args, **kwargs): start_time = time() # 保留原函数的返回值 result = func(*args, **kwargs) execution_time = time() - start_time # 获取函数签名,匹配位置参数与形参名 sig = inspect.signature(func) param_names = list(sig.parameters.keys()) # 生成带参数名的位置参数字符串 positional_args = [f"{param_names[i]}={arg}" for i, arg in enumerate(args)] # 生成关键字参数字符串(排除已通过位置传入的参数) keyword_args = [f"{k}={v}" for k, v in kwargs.items() if k not in param_names[:len(args)]] # 格式化日志内容 args_str = ', '.join(positional_args) if positional_args else '' kwargs_str = ', '.join(keyword_args) if keyword_args else '' log_line = f"{func.__name__}; args: {args_str}; kwargs: {kwargs_str}; execution time: {execution_time:.2f} sec.\n" with open('log.txt', 'a+') as file: file.write(log_line) return result return wrapper
关键修改点
- 参数名绑定:通过
inspect模块解析函数签名,将位置参数与对应形参名关联,生成a=1格式的参数字符串,替代原代码的元组格式。 - 格式统一修正:调整日志分隔符为分号,移除多余换行保证
sec.与时间值在同一行,用:.2f格式化执行时间为两位小数,匹配预期格式。 - 保留原函数返回值:原装饰器未返回被装饰函数的执行结果,修改后保存并返回该结果,避免丢失业务逻辑返回值。
- 参数去重:过滤掉已通过位置传入的关键字参数,避免重复记录。
内容的提问来源于stack exchange,提问作者Jack Heathrow
相关产品推荐
相关产品推荐

