Определение функции в 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!'
Ответы
Ответ 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