如何解析inspect.formatargvalues格式化字符串并提取参数为字典?
处理含复杂参数的
inspect.formatargvalues字符串转字典问题 这个问题我之前也碰到过!直接按逗号拆分参数的方法太脆弱了,遇到值里带逗号或者嵌套括号的情况就直接歇菜。给你分享一个能覆盖所有场景的解决方案,核心思路是利用Python的语法解析能力来准确区分参数分隔符和值内部的符号。
方案:用ast模块解析语法结构
Python的ast模块是官方提供的语法解析工具,能正确识别Python的语法元素(比如字符串、布尔值、None、嵌套括号等),完美解决参数值里混有逗号的问题。下面是完整的实现代码:
import ast import re def parse_call_args(call_str): # 先提取函数调用括号内的参数内容 if '(' not in call_str or ')' not in call_str: return {} start_idx = call_str.index('(') + 1 end_idx = call_str.rindex(')') args_content = call_str[start_idx:end_idx].strip() if not args_content: return {} try: # 构造临时函数调用表达式,让ast可以解析参数 temp_expr = f"dummy_func({args_content})" tree = ast.parse(temp_expr, mode='eval') kwargs = tree.body.keywords params_dict = {} for kw in kwargs: # 处理可直接解析的常量(字符串、数字、布尔、None) if isinstance(kw.value, ast.Constant): params_dict[kw.arg] = kw.value.value else: # 对于枚举、自定义对象的字符串表示(比如<Tab.Chrome: 'tab-chrome'>),保留原字符串 params_dict[kw.arg] = ast.unparse(kw.value) return params_dict except SyntaxError: # 兼容无引号的字符串参数(比如x=something good这种非标准写法) # 用正则匹配平衡括号的参数 param_pattern = r'(\w+)=((?:[^(),]+|\([^()]*\))+)(?:,|$)' matches = re.findall(param_pattern, args_content) params_dict = {} for key, val_str in matches: val_str = val_str.strip() # 尝试解析为Python常量 try: params_dict[key] = ast.literal_eval(val_str) except (SyntaxError, ValueError): # 解析失败则保留原字符串(去掉多余引号) if val_str.startswith(('"', "'")) and val_str.endswith(('"', "'")): params_dict[key] = val_str[1:-1] else: params_dict[key] = val_str return params_dict # 测试你的示例输入 input_content = """CALL function.a(timeout_secs=10) CALL function.b(x=something good (happy days, ABC 123), y_z=None, check_this=True, check_this_2=None, extra_info=None, press=False, timeout_secs=30) CALL function.c(key='A_B') CALL function.d(target=<Tab.Chrome: 'tab-chrome'>) CALL function.e(music_type=<MusicType.ALBUM: 1>, term=None, genre=None, results=True) CALL function.f(button='END', delay=None)""" # 拆分每个CALL语句 call_statements = [stmt.strip() for stmt in input_content.split('CALL ') if stmt.strip()] # 逐个解析并输出结果 for stmt in call_statements: func_name = stmt.split('(')[0] args_dict = parse_call_args(stmt) print(f"✅ 函数 {func_name} 的参数字典:") print(args_dict) print("---")
这个方案的优势
- 覆盖所有场景:不管是带逗号的嵌套括号参数、标准的Python常量(None/True/False/字符串/数字),还是枚举、自定义对象的字符串表示,都能正确提取。
- 容错性强:即使遇到无引号的非标准字符串参数(比如
x=something good),也能通过正则兜底处理。 - 稳定性高:基于官方语法解析工具,比手写正则更可靠,不容易出现边缘情况的bug。
运行上面的代码后,你会得到每个函数调用对应的参数字典,完全不会像之前那样把x=something good (happy days, ABC 123)拆成多个参数。
内容的提问来源于stack exchange,提问作者QCFia
相关产品推荐
相关产品推荐

