如何将外部传入的字符串转换为Python的**kwargs参数
解析外部字符串为Python kwargs参数
问题背景
需要将类似"a = [1,2], b= False, c =('abc', 'efg'),d=1"的外部字符串转换为Python可识别的kwargs字典,要求对空格差异鲁棒,支持标准类型(int、bool等)和可迭代对象(list、tuple等),输入格式为key=value逗号分隔形式,可先移除所有空格简化解析。
解决方案1:使用AST模块(推荐)
ast模块是Python标准库的一部分,能安全解析Python字面量,避免eval的安全风险,且对各种标准类型支持完善。
实现代码
import ast def str_to_kwargs(input_str): # 移除所有空格,消除格式差异 cleaned_str = input_str.replace(" ", "") # 包裹为字典字面量格式 dict_literal = f"{{{cleaned_str}}}" # 解析抽象语法树 tree = ast.parse(dict_literal, mode='eval') dict_node = tree.body kwargs = {} for key_node, value_node in dict_node.items: # 提取键名(标识符) key = key_node.id # 安全求值得到Python原生对象 value = ast.literal_eval(value_node) kwargs[key] = value return kwargs # 测试示例 input_str = "a = [1,2], b= False, c =('abc', 'efg'),d=1" kwargs_result = str_to_kwargs(input_str) print(kwargs_result) # 输出: {'a': [1, 2], 'b': False, 'c': ('abc', 'efg'), 'd': 1}
优势
- 安全:
ast.literal_eval仅解析Python字面量,不会执行任意代码 - 全面:支持所有Python标准字面量类型(int、float、bool、list、tuple、str、dict、None等)
- 简洁:代码量少,无需复杂的语法定义
解决方案2:改进Pyparsing实现
如果必须使用Pyparsing,需要调整语法规则,使其能识别各种Python标准类型,同时消除空格影响。
实现代码
from pyparsing import * def str_to_kwargs_pyparsing(input_str): # 移除所有空格 cleaned_str = input_str.replace(" ", "") # 定义Python字面量解析规则 py_literal = (pyparsing_common.number | oneOf("True False None") | quotedString.setParseAction(removeQuotes) | nestedExpr('[', ']') | nestedExpr('(', ')')) # 定义键值对规则:标识符 = 字面量 key_value = Group(Word(alphas, alphanums + "_") + Suppress('=') + py_literal) # 整体语法:逗号分隔的键值对 kwargs_grammar = delimitedList(key_value) # 解析字符串 parsed_items = kwargs_grammar.parseString(cleaned_str) kwargs = {} for item in parsed_items: key = item[0] raw_value = item[1] # 处理嵌套的list/tuple if isinstance(raw_value, ParseResults): value_list = raw_value.asList() # 根据开头符号判断是list还是tuple if cleaned_str[cleaned_str.find(key)+len(key)+1] == '(': value = tuple(value_list) else: value = value_list else: # 转换布尔值和None为原生类型 if raw_value == 'True': value = True elif raw_value == 'False': value = False elif raw_value == 'None': value = None else: value = raw_value kwargs[key] = value return kwargs # 测试示例 input_str = "a = [1,2], b= False, c =('abc', 'efg'),d=1" kwargs_result = str_to_kwargs_pyparsing(input_str) print(kwargs_result) # 输出: {'a': [1, 2], 'b': False, 'c': ('abc', 'efg'), 'd': 1}
说明
- 用
pyparsing_common.number处理数字,quotedString处理字符串,nestedExpr处理嵌套的list/tuple - 通过
oneOf匹配布尔值和None,并转换为Python原生类型 - 先移除所有空格,避免空格对解析的干扰
内容的提问来源于stack exchange,提问作者keynesiancross
相关产品推荐
相关产品推荐

