Модель оценки параметров функции Python

Я просматривал статью на веб-сайте Питера Норвига, где он пытается ответить на следующий вопрос (кстати, это не мой вопрос): «Могу ли я сделать эквивалент (тест? Результат: альтернатива) в Python?»

вот один из предложенных им вариантов,

def if_(test, result, alternative=None):
    "If test is true, 'do' result, else alternative. 'Do' means call if callable."
    if test:
        if callable(result): result = result()
        return result
    else:
        if callable(alternative): alternative = alternative()
        return alternative

И вот пример использования.

>>> fact = lambda n: if_(n <= 1, 1, lambda: n * fact(n-1))
>>> fact(6)
720

Я понимаю, как это работает (я думаю), но я просто играл с кодом и решил посмотреть, что произойдет, когда я изменю третий аргумент в определении «факт» выше на n * факт (n-1), что то есть измените его на невызываемое выражение. При его запуске интерпретатор входит в бесконечный цикл. У меня есть довольно хорошее представление о том, почему это происходит, то есть функция if_ возвращает то же самое выражение, которое она получает. Но каков тип этого выражения? Что именно здесь происходит? Я не ищу подробного объяснения, а просто некоторые указатели на модель оценки Python, которые могут помочь моему пониманию.

Спасибо!


person fsm    schedule 26.04.2010    source источник
comment
Вероятно, это не связано, но вы можете просто использовать result if test else alternative.   -  person kennytm    schedule 26.04.2010


Ответы (1)


Причина, по которой цикл никогда не завершается, когда вы меняете fact на n * fact(n-1), заключается в том, что n * fact(n-1) должен вычисляться первым (как третий аргумент if). Его оценка приводит к другому вызову fact, до бесконечности (поскольку больше нет никакого базового случая, чтобы остановить его).

Ранее вы передавали объект функции (lambda), который не будет оцениваться до тех пор, пока не будет получено тело if, а его результат будет проверен через test.

Это известно (я полагаю) как активная оценка, когда аргументы функции оцениваются до того, как они будут переданы в функцию. В схеме отложенной оценки аргументы не будут оцениваться до тех пор, пока они не будут использованы в теле функции.

person danben    schedule 26.04.2010
comment
Если n‹=1 будет вычислено правильно, рекурсия остановится на n = 1, возвращая 1. - person Krab; 26.04.2010
comment
n <= 1 будет оцениваться, но его значение никогда не проверяется до тех пор, пока оно не окажется внутри тела функции. Когда он использует рекурсивное выражение вместо лямбда в качестве третьего параметра, тело функции никогда не достигается. - person danben; 26.04.2010
comment
Я не утверждал, что он вычисляет n!, я просто неправильно понял ваш ответ. Сейчас еще раз перечитал и согласен. - person Krab; 26.04.2010
comment
@fsm - пожалуйста. Если вы нашли этот ответ полезным, я был бы признателен, если бы вы отметили его как принятый. - person danben; 27.04.2010