2013-07-22 1 views
2

У меня есть некоторые математические функции (представленные в виде строк) в файле:Заменить «**» с «Math.pow» в Python

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 

Edit 2: Thanx все для ответа, я, наконец, нашел, как это сделать, и ваши ответы и комментарии помогли мне. я просто должен был заставить поплавок деление с следующей строкой в ​​верхней части моего файла:

 from __future__ import division 
+0

вы хочет 'Math.pow (1 + а, (б/(3 * а + 1)))' ? –

+3

Вы знаете, что есть правильный оператор '**' в python? –

+1

Для этого требуется более простая замена текста; вам нужно создать правильное дерево разбора каждого выражения и регенерировать выражение после замены оператора вызовом функции. –

ответ

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) 
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')