我正在编写一个程序,用户需要能够使用包含numpy和scipy函数的自编数学函数,例如. scipy.special.wofz().
这些函数将存储在文件中,并由程序作为字符串导入.我环顾四周,看到eval()或exec()不是一种安全的方法.
例如. here.
安全问题是好的用户从访问好用户系统的恶意用户加载文件.
我在考虑做这样的事情:
#!/bin/python
from scipy.special import *
from numpy import *
import sympy
# Define variable a
vars = {"a":1}
# This is the string I get from a file
string = "wofz(a)"
parsed_string = sympy.sympify(string)
parsed_string.evalf(subs=vars)
但是,这不起作用.它只返回:
wofz(a)
wofz(a)未经评估.这甚至应该以这种方式工作吗?
我有另一个想法:
所以我想,一旦这个数学函数得到了认可,就应该是安全的.我可以简单地做这样的事情:
globals = {wofz:wofz}
eval(str(parsed_string), vars, globals)
哪个工作正常并返回:
(0.36787944117144233+0.60715770584139372j)
这样安全吗?我知道这不好.
请帮忙.
解决方法:
使用sympy,这是一种更安全的选择.
import sympy
from sympy.core.function import Function
from sympy.core import S
from sympy import sympify
from sympy.functions import im
from scipy.special import wofz
class Wofz(Function):
is_real = True
@classmethod
def _should_evalf(csl,arg):
return True
def as_base_exp(cls):
return cls,S.One
def _eval_evalf(cls, prec):
return sympy.numbers.Number(im(wofz(float(cls.args[0]))))
print sympify("Wofz(2)",{'Wofz':Wofz}).evalf()
输出(你必须以某种方式处理虚部):
0.340026217066065