python如何输入一个字符串执行方法_[求教] 如何实现一个沙盒机制来执行来自字符串的 Python 代码...

#背景

手头的项目是关于科学计算的。一个大的数据集,分别由以下几个文件组成:

+ crdArr => N个数据的坐标;

+ labelDict => N个数据的数据属性字典,如 labelDict["some_key"] 里面存着一个长度为N的某种属性的数据,相当于一个 speadsheet,key 作为 header 的索引键;

+ disMtx => N*N 的距离矩阵。

程序需要根据 labelDict 中的属性用数学表达式从 N 个数据中得到一个子集的 subset Index。每一个 subset index 作用到原有数据集会得到一个子集,这个子集生成一个叫做 collection 的对象然后交给后面的模块。。。

过去选取子集的代码都是写死在 python 里,用 Numpy (一个科学计算的 python 库,类似 Matlab),后来为了灵活,我在外面写了一个 json 的配置文件,把要设置的参数全部放进去。so far so good。

问题是,选取子集需要一个可能互相嵌套的数学表达式,比如:

idx = (labelDict["age"] > 30 && labelDict["age"] < 40) && (labelDict["occupation"] == "teacher")

这种表达式很容易用 numpy 的语法实现。但是 json object 是一个较为 flat 的结构,我没法在里面实现数学表达式的复杂逻辑和互相嵌套。目前在 json 文件中我只能把选取逻辑做成一个 list,然后一条一条的做逻辑运算,但很显然这种平坦结构的表达无法实现嵌套,可是如果用 json 来写一个数学表达式显然不合适。

还有一个原因,就是这个项目需要用户在程序执行的时候动态选取一个子集,这就是没法把选取子集的代码写死在 python 里的原因,同样,json 的配置文件也只是一个暂时的策略。我需要一个 GUI 来让用户输入可能的数学表达式来提取他子集需要的数据子集。所以我没法用 GUI 的控件来让用户设定子集选取表达式,而是想叫用户直接在文本框输入这种表达式。问题来了!!

# 问题

我觉得我完全没必要自己重新发明一个 正则表达式来 parse 用户输入的表达式,或者导入什么 Excel 的模块来完成这个任务。因为 Numpy 的语法本身就很清晰易懂。

所以我决定用 Python 自己的 eval 或者 complie 来提取用户在文本框输入的 Numpy 表达式。

可是,,,

首先这种方式很不安全,用户可以输入任何 python 代码,虽然我的程序不是网络程序,只是个科学计算软件,但是总觉得不放心。

理想方式是创建一个沙河机制,用户在文本框输入的 numpy 表达式在一个沙盒中 eval,有限的 namespace,有限的权限。这样基本上限制用户只能输入应该输入的。

# 实验

我刚刚做了个实验,写了一个 py 文件:

arr = array([1,2,3,4])

ss = sum(arr)

用 python 直接执行这个文件是不行的,因为 array() 函数不在命名空间中。

然后我打开 ipython

$ ipython

$ from numpy import array

$ excufile("the_file_I_mentioned_above.py")

$ print arr

$ print ss

以上可以执行,说明 excufile 是不管上下文的,需要我提前配置好上下文环境。

可问题是,我怎样限制用户在 eval 里面的输入,如何创建一个安全的执行环境?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值