我正在用Python编写一段代码,可以用来求解方程。用户必须首先通过raw_input()输入一个代码,然后用它来计算eval()循环中每个x的y,如下所示:
#some imports (math) and other irrelevant code
Code = raw_input('please enter your equation')
Low = raw_input('please enter the lowest number in the domain')
High = raw_input('please enter the highest number in the domain')
X = Low
While X <= High:
Y = eval(code)
#complicated code to solve equation
X += #number depending on the amount of decimals
#simpler code to print the result
问题是,对每个循环使用eval()解析输入代码的速度非常慢。有没有一种方法可以只解析代码一次,然后将其用作程序其余部分的函数?
您可以使用compiler.compile()
提前编译表达式(自Python v2.6以来已弃用)。
使用Python 3.x:
compile
功能是内置的- AST模块提供类似的功能
还可以看看:Python:如何加速重复执行的eval语句?
编辑
一些例子:
>>> expr = 'x*x + 2*x + 1'
>>> expr_obj = compile(expr, '', 'eval')
>>> x = 1
>>> y = eval(expr)
现在
>>> y
4
>>> x = 2
>>> y = eval(expr)
>>> y
9
compile
是eval
(和exec
)的较低级别版本。它不计算/执行你的表达式/语句,而是返回一个可以执行的代码对象
PS作为一条一般规则,当对用户提交的字符串使用eval
时,您必须非常小心地接受什么(这是一个潜在的安全漏洞)。
如果代码中的等式不需要任何对X的引用,那么您可以将Y = eval(code)
移到循环之外。否则,您需要它在此位置访问X及其当前值。
如果用户根据单个变量"X"输入方程,则可以使用Python的lambda
关键字将其转换为函数:
CodeAsFunction = eval('lambda X : ' + Code)
(为了实现这一点,用户只需输入等式的右侧3*X + 100
,而不是Y = 3*X+100
。)
然后在循环的主体中,您可以调用以下函数:
while X = High:
Y = CodeAsFunction(X)
... etc. ...
请注意,eval
现在只被调用一次,以创建可调用的CodeAsFunction
变量。
当然,你必须注意安全问题,正如其他海报已经提到的那样。