Подтвердить что ты не робот

Определение функции в Python занимает много времени

Почему python пытается вычислить значение p во время определения? Для определения этой функции требуется возраст.

def f():
    raise Exception('Some error')
    p = 2322111239**42322222334923492304923

print 'Defined!'

Также, если во время определения вычисляется значение p, почему можно определить эту функцию без ошибок?

def f():
    return 4
    p = 11/0

Этот явно работает отлично, потому что константы не задействованы:

def f():
    raise Exception('Some error')
    x=42322222334923492304923
    p = 2322111239**x

print 'Defined!'
4b9b3361

Ответ 1

Это оптимизатор глазок:

http://hg.python.org/cpython/file/eabff2a97b5b/Python/peephole.c#l88

См., в частности, строки 104-106

case BINARY_POWER:
    newconst = PyNumber_Power(v, w, Py_None);
    break;

Цель состоит в том, чтобы ускорить выполнение функции во время выполнения за счет более медленного определения (read: import). Это имеет смысл, потому что вам нужно только один раз выполнить компиляцию кода для функции, но вам может потребоваться многократно ее вызвать.

Я считаю, что оптимизатор был написан Раймондом Хеттингером, который довольно активен в SO, возможно, он может подтвердить мои претензии.

Ответ 2

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

Ответ 3

Попробуйте более разумное число:

>>> def f():
...    p=123**45
... 

Если вы используете dis для просмотра байтовых кодов, вы можете видеть, что значение для p определяется до того, как функция вызывается

>>> import dis
>>> dis.dis(f)
  2           0 LOAD_CONST               3 (11110408185131956285910790587176451918559153212268021823629073199866111001242743283966127048043)
              3 STORE_FAST               0 (p)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE