如何在Python中实现打印函数名及调用参数的@traced装饰器?
修正@traced装饰器以输出指定格式的函数调用日志
完整修正代码
import inspect def traced(func): def wrapper(*args, **kwargs): # 获取函数签名并绑定传入的参数 sig = inspect.signature(func) bound_args = sig.bind(*args, **kwargs) bound_args.apply_defaults() # 构建参数字符串:区分位置参数与关键字参数 param_strings = [] for param_name in sig.parameters: arg_value = bound_args.arguments[param_name] # 如果参数是通过关键字传入的,保留key=value格式;否则直接写值 if param_name in kwargs: param_strings.append(f"{param_name}={repr(arg_value)}") else: param_strings.append(repr(arg_value)) # 拼接成目标格式并打印 call_log = f"{func.__name__}({', '.join(param_strings)})" print(call_log) # 执行原函数逻辑 return func(*args, **kwargs) return wrapper @traced def foo(a,b): if a == 0: return b return foo(b=a-1,a=b-1) # 测试示例 foo(4, 5)
关键逻辑说明
- 参数绑定与区分:通过
inspect.signature和bind()方法获取绑定后的参数对象,遍历函数签名的参数列表,结合调用时的kwargs判断参数是位置传入还是关键字传入。 - 格式拼接:位置参数直接输出值的字符串表示,关键字参数输出
参数名=值的格式,最后拼接成函数名(参数列表)的目标格式。 - 默认参数处理:调用
apply_defaults()确保如果函数有默认参数且未传入时,也能正确输出默认值(如果需要的话)。
测试输出
调用foo(4,5)会得到如下输出:
foo(4, 5) foo(a=4, b=3) foo(a=2, b=3) foo(a=2, b=1) foo(a=0, b=1)
完全符合要求的格式:位置参数无标注,关键字参数保留key=value形式。
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

