更换'**';与';math.pow';用Python

更换'**';与';math.pow';用Python,python,parsing,pow,Python,Parsing,Pow,我在文件中有一些数学函数(表示为字符串): 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

我在文件中有一些数学函数(表示为字符串):

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

您可以使用以下转换器:

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)
对于文件中的行:
node=ast.parse(行,mode=“eval”)
node=PowForDoubleStar()。访问(节点)
代码=编译(节点“”,mode=“eval”)
a、 b=1,3
结果=评估(代码)

您似乎试图避免的是长整数算术,它可能需要任意长的执行时间。解决此问题的最简单方法是:

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')
node=ast.parse(“(3**100**100**2)”,mode=“eval”) >>>node=Floatify()。访问(节点) >>>代码=编译(节点“”,mode=“eval”) >>>评估(代码) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 评估(代码) 文件“”,第1行,在 溢出错误:(34,‘结果太大’)
您知道python中有一个
**
操作符,对吗?这需要的不仅仅是简单的文本替换;您需要为每个表达式创建一个正确的解析树,并在使用函数调用替换运算符后重新生成表达式?可能有一种更简单的方法来实现您的总体目标,而不是在python代码上查找/替换将所有数字文本处理为浮点数也可以解决这个问题
>>> 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')