Python3如何让dbg调试打印自动输出变量名与对应数值?
实现方案
核心思路
通过Python的inspect模块获取dbg函数调用处的源码,解析出传入参数的原始表达式字符串,再和实际参数值配对格式化输出,全程不需要修改现有代码里的dbg调用逻辑,完全兼容你原来的一键开关调试的使用习惯。
完整实现代码
import inspect import re def dbg(*args): # 获取调用dbg的栈帧信息 caller_stack = inspect.stack()[1] # 读取调用位置所在的源码段 source_lines, start_line = inspect.getsourcelines(caller_stack.frame) call_offset = caller_stack.lineno - start_line # 处理跨多行的dbg调用,匹配完整的dbg(...)范围 raw_call_code = "" bracket_count = 0 in_string_tag = None for line_idx in range(call_offset, len(source_lines)): current_line = source_lines[line_idx] for char_idx, char in enumerate(current_line): # 跳过字符串内部的括号,避免解析错误 if char in ("'", '"') and (char_idx == 0 or current_line[char_idx-1] != "\\"): if in_string_tag == char: in_string_tag = None elif in_string_tag is None: in_string_tag = char if in_string_tag is None: if char == "(": bracket_count += 1 elif char == ")": bracket_count -= 1 if bracket_count == 0: raw_call_code += current_line[:char_idx+1] break if bracket_count == 0: break raw_call_code += current_line # 提取dbg的参数表达式字符串 param_match = re.search(r"dbg\((.*)\)", raw_call_code, re.DOTALL) if not param_match: return param_raw_str = param_match.group(1) # 拆分多个参数,处理嵌套括号、字符串内逗号的场景 param_expr_list = [] current_expr = "" nested_level = 0 in_str = None for char in param_raw_str: if char in ("'", '"') and (not current_expr or current_expr[-1] != "\\"): if in_str == char: in_str = None elif in_str is None: in_str = char if in_str is None: if char == "(": nested_level += 1 elif char == ")": nested_level -= 1 elif char == "," and nested_level == 0: param_expr_list.append(current_expr.strip()) current_expr = "" continue current_expr += char if current_expr.strip(): param_expr_list.append(current_expr.strip()) # 格式化输出 output_items = [f"{expr} = {repr(val)}" for expr, val in zip(param_expr_list, args)] print(", ".join(output_items)) # 关闭调试时直接替换为下面的空函数即可 # def dbg(*args): pass
效果验证
用你示例的场景测试:
x = 0 y = 15 def f(v): return 32 dbg(x, y, f(x))
运行后输出结果完全符合要求:
x = 0, y = 15, f(x) = 32
注意事项
- 完全兼容你现有所有
dbg(...)调用,不需要做任何修改 - 支持参数多行书写、参数带嵌套函数/括号、字符串参数等场景
- 调试关闭时切换为空函数即可,无任何额外性能开销
内容的提问来源于stack exchange,提问作者bohdan_trotsenko
相关产品推荐
相关产品推荐

