You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何将含无引号键的键值对字符串转换为字典

问题场景

Python开发过程中,需要将包含无引号非字符串键的键值对字符串转换为字典类型,待处理的示例代码如下:

employee='{"Priority":{0:"High"},"Age":{range(0,5):"high"}}'

实现方法

首先明确两个常规方案的局限性:

  • json.loads() 完全无法处理这类字符串:JSON规范强制要求对象键必须是双引号包裹的字符串,且不支持range这类Python特有表达式,直接调用会报解析错误。
  • ast.literal_eval() 也不能直接用:这个安全解析方法仅支持原生字面量类型(数字、字符串、列表、字典、元组、布尔值、None),range()属于函数调用,不在它的允许范围内,直接调用会抛ValueError。

根据你的数据源可信程度,可以选下面两种方案实现:

方案1:可信数据源下的轻量实现

如果待转换的字符串是内部生成、完全可控没有注入风险的,可以用eval搭配受限命名空间快速转换,屏蔽掉危险内置方法,仅保留需要的range:

employee_str = '{"Priority":{0:"High"},"Age":{range(0,5):"high"}}'
# 限制全局命名空间,切断危险内置函数的访问路径,仅暴露range
safe_ns = {"__builtins__": {"range": range}}
employee = eval(employee_str, safe_ns)

执行后得到的就是标准字典:

print(employee)
# 输出: {'Priority': {0: 'High'}, 'Age': {range(0, 5): 'high'}}
print(employee["Priority"][0]) # 输出: High
print(employee["Age"][range(0,5)]) # 输出: high

注意:这个方法禁止用来处理用户提交、外部传入的不可信字符串,避免代码注入风险。

方案2:不可信数据源下的安全实现

如果要处理来源不确定的字符串,可以基于AST做白名单解析,只允许你需要的语法结构通过,从根源上堵死注入风险,示例代码如下:

import ast

def safe_parse_dict(s: str) -> dict:
    def _traverse_node(node):
        if isinstance(node, ast.Expression):
            return _traverse_node(node.body)
        # 解析字典结构
        if isinstance(node, ast.Dict):
            return {_traverse_node(k): _traverse_node(v) for k, v in zip(node.keys, node.values)}
        # 解析常量(字符串、数字、None等)
        if isinstance(node, ast.Constant):
            return node.value
        # 仅允许range函数调用,参数必须为合法字面量
        if isinstance(node, ast.Call):
            if not (isinstance(node.func, ast.Name) and node.func.id == "range"):
                raise ValueError("解析错误:存在不允许的函数调用")
            args = [_traverse_node(arg) for arg in node.args]
            return range(*args)
        # 兼容Python3.8以下版本的字面量节点
        if isinstance(node, ast.Num):
            return node.n
        if isinstance(node, ast.Str):
            return node.s
        raise ValueError(f"解析错误:存在不支持的语法结构 {type(node)}")
    ast_tree = ast.parse(s, mode="eval")
    return _traverse_node(ast_tree)

# 调用示例
employee_str = '{"Priority":{0:"High"},"Age":{range(0,5):"high"}}'
employee = safe_parse_dict(employee_str)

这个解析器遇到任何不在白名单里的语法(比如导入模块、执行系统命令的表达式)都会直接抛错,安全性可以满足生产环境处理外部输入的要求。


内容的提问来源于stack exchange,提问作者Rahul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:18:09