2015-05-16 5 views
1

Ниже представлено дерево выражений для выражения вызова mul(add(2, mul(4, 6)), add(3, 5)).Оценка выражения вызова

enter image description here


В приведенном ниже коде,

from operator import mul 

def square(x): 
    print('In square with value: ' + str(x)) 
    return mul(x, x) 

def repeat(f, n): 
    def identity(x): 
     return x  
    def apply_n_times(x): 
     return repeat(f,n-1)(f(x)) 
    if n < 0: 
     raise ValueError("Cannot apply a function %d times" % (n)) 
    elif n == 0: 
     return identity 
    else: 
     return apply_n_times 
g = repeat(square, 2)(5)  
print(g) 

Как я оцениваю называть выражение repeat(f, n-1)(f(x)) в коде выше, когда f является функцией, а n и x являются целыми числами.

+0

... Обычный способ? –

+0

@ IgnacioVazquez-Abrams, когда 'f (x)' in '(f (x))' получает оценку перед 'repeat()' или после 'repeat()'? Как я могу решить этот поток? – overexchange

+0

Зависит от реализации компилятора. И это не имеет значения, поскольку ни один из вызовов не имеет побочных эффектов, которые влияют на другие. –

ответ

1

Выражения вычисляются from left to right в Python:

В следующих строках выражения будут оценены в арифметическом порядке их суффиксов:

expr1, expr2, expr3, expr4 
(expr1, expr2, expr3, expr4) 
{expr1: expr2, expr3: expr4} 
expr1 + expr2 * (expr3 - expr4) 
expr1(expr2, expr3, *expr4, **expr5) 
expr3, expr4 = expr1, expr2 

В этом случае, это означает, что return repeat(f, n-1)(f(x)) работает следующим образом:

tmp1 = repeat(f, n-1) 
tmp2 = f(x) 
return tmp1(tmp2) 

... за исключением того, что он не создает эти дополнительные переменные.

Любая разумная реализация должна удовлетворять этим правилам, а не только CPython.

+0

Не могли бы вы нарисовать дерево выражений? – overexchange

+0

Потому что, как вы сказали, 'tmp1' будет сначала оценен. Но в соответствии с операциями отладки 'tmp2' сначала получает оценку.'In apply_n_times с: 2 | В квадрате со значением: 5 | В apply_n_times с: 1 | В квадрате со значением: 25 | 625'. В соответствии с вашим ответом последовательность должна быть: 'В apply_n_times с: 2 | В apply_n_times с: 1 | ... ' – overexchange

+0

Это [поток] (https://github.com/shamhub/paradigms_using_python/blob/master/scn.png), который я ожидал. Написание 'tmp1 (tmp2)' не дает мне этой интуиции. – overexchange

0

Простой способ проверить это с помощью глобальных переменных.

tester = 0 

def test_1(): 
    global tester 
    print(tester, "from test_1") 
    tester = 1 
    return lambda x: None 

def test_2(): 
    global tester 
    print(tester, "from test_2") 
    tester = 2 
    return None 

test_1()(test_2()) 

и печатает:

0 from test_1 
1 from test_2 

в Python 3 (и эквивалент в 2) с компилятором из python.org так, кажется, идет слева направо.

Возможно, вам придется протестировать его с вашим компилятором, чтобы получить результат, так как это зависит от компилятора.

+0

Python не C. Порядок оценки четко определен, как показано в моем ответе. – Kevin

Смежные вопросы