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

Python中替代eval读取dat文件内容转换为numpy数组的方案咨询

可行的替代方案

方案1:优先调整存储格式(最高效安全)

如果可以修改dat文件的生成逻辑,直接使用numpy原生的序列化格式是最优选择:

  • 写文件时调用np.save('trial.npy', 待存储的数组)
  • 读文件时直接加载:
import numpy as np
x_1 = np.load('trial.npy', allow_pickle=False)
y = np.concatenate(x_1)

该方案完全规避字符串解析的安全风险,读写速度远高于文本解析,无需处理字符串匹配逻辑。

方案2:无法修改存储格式时,用AST白名单解析

如果必须保留现有带np.repeat这类numpy调用的文本存储格式,用AST(抽象语法树)白名单机制替代eval,仅允许你指定的合法语法和函数调用,完全拦截恶意代码:

import numpy as np
import ast

# 配置允许的numpy函数白名单,按需添加你用到的numpy方法
ALLOWED_NP_FUNCS = {'repeat'}

def safe_eval_np(expr):
    # 解析表达式为AST节点
    tree = ast.parse(expr, mode='eval')
    # 遍历所有节点校验合法性
    for node in ast.walk(tree):
        # 允许的节点类型:表达式、列表、数字、常量、属性访问、调用
        if isinstance(node, (ast.Expression, ast.List, ast.Num, ast.Constant, ast.Attribute, ast.Call, ast.Load)):
            # 校验numpy调用是否在白名单
            if isinstance(node, ast.Attribute):
                if node.value.id != 'np' or node.attr not in ALLOWED_NP_FUNCS:
                    raise ValueError(f"非法调用:np.{node.attr} 不在白名单")
            continue
        # 其他节点类型直接拦截
        raise ValueError(f"非法语法:{type(node).__name__} 不被允许")
    # 校验通过后执行
    return eval(compile(tree, filename='<ast>', mode='eval'))

# 适配你原来的读取逻辑
with open('trial.dat', 'r') as f:
    data = f.readlines()
    data = [(d+' ')[:d.find('#')].rstrip() for d in data]

x_1 = safe_eval_np(data[0])
y = np.concatenate(x_1)

你给出的示例字符串[[1,2,np.repeat(3,1)]]可以正常通过该函数解析,得到和原eval完全一致的结果。如果后续用到其他numpy方法,直接添加到ALLOWED_NP_FUNCS集合即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:15:06