О компиляции и (полу)компиляции в CPython

Всем известно, что Python — интерпретируемый язык программирования. Но это не совсем точно, конечно. Чтобы употреблять такие слова, нужно говорить о какой-то конкретной имплементации языка.Что же, давайте попробуем начать сначала.

Дубль два

Всем известно, что CPython (самая распространенная имплементация) интерпретируемый! Но это не совсем точно, конечно. Можно сказать, что CPython полукомпилируемый, потому что исходный код компилируется в байт-код, который потом исполняется виртуальной машиной (тоже CPython в данном случае).

Традиционно же, когда мы говорим о компиляции, мы имеем в виду преобразование высокоуровневого языка в конкретный машинный код. У этой (полу)компиляции в Python есть свои особенности.

Исходный код можно скомпилировать в байт-код с разными флагами оптимизации: -О, -ОО. В результате у вас появятся *.pyo файлики с байт-кодом. При этом в первом случае у вас будут «выключены» assert'ы, а во втором — ещё «вырежутся» docstring'и. Оптимизации не особо крутые, чего уж тут говорить, если только в asserta'ах не было какой-то сложной логики.

И что это значит с практической точки зрения?

Как это знание может пригодиться? Например, если код разворачивается на CentOS с помощью rpm-пакетов, то во время сборки пакета неявно запускается brp-python-bytecompile скрипт, который компилирует Python файлы в .pyc и .pyo. Поэтому не стоит потом удивляться, что assert'ы в коде не срабатывают.

Хотите задать вопрос? Пишите комментарий!