我在文件中有一些数学函数(表示为字符串):
1+a**(b/(3*a+1))
(1+a)**(b/(3*a+1))
...
如何将字符串中的所有**
转换为math.pow
?
编辑:我想解决的问题如下: 我有很多这样的功能要评估,我不能在一个上花太多时间。
有时功能看起来像这样:
(3**100**100**2)
Python尝试评估它,这是非常长的。 我希望有一个错误,如:
>>> math.pow(3, math.pow(100, 100))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: math range error
编辑2:Thanx全部回答,我终于找到了怎么做,你的答案和评论对我帮助很大。 我只需要在我文件顶部的下一行强制浮点除法:
from __future__ import division
答案 0 :(得分:3)
您可以使用以下变换器:
import ast
pow_func = ast.parse("math.pow", mode="eval").body
class PowForDoubleStar(ast.NodeTransformer):
def visit_BinOp(self, node):
node.left = self.visit(node.left)
node.right = self.visit(node.right)
if isinstance(node.op, ast.Pow):
node = ast.copy_location(
ast.Call(func=pow_func,
args=[node.left, node.right],
keywords=[]
),
node
)
return node
在您的特定示例中,您可以使用
执行这些代码部分for line in file:
node = ast.parse(line, mode="eval")
node = PowForDoubleStar().visit(node)
code = compile(node, "<string>", mode="eval")
a, b = 1, 3
result = eval(code)
答案 1 :(得分:0)
你在这里试图避免的是长整数运算,这可能需要花费大量的时间来执行。解决此问题的最简单方法是:
class Floatify(ast.NodeTransformer):
def visit_Num(self, node):
return ast.Num(float(node.n))
使用时:
>>> node = ast.parse("(3**100**100**2)", mode="eval")
>>> node = Floatify().visit(node)
>>> code = compile(node, "<string>", mode="eval")
>>> eval(code)
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
eval(code)
File "<string>", line 1, in <module>
OverflowError: (34, 'Result too large')