UPD: спасибо Konrad и kqr за то, что он указал только на этот вопрос только о компиляции стиля C или C++. Есть и другие способы сделать это, например, Common Lisp.
Строго говоря, вы не можете скомпилировать программу python заранее, потому что у вас не обязательно полный код во время компиляции. Программа python может загружать исходный код и передавать его через eval()
для всего, что мы знаем. Или постройте его программно (в стандартной библиотеке он фактически делает именно это в namedtuple()
).
Это не самая большая проблема, хотя - это маргинальные практики. Самая большая проблема заключается в том, что это невероятно сложно, возможно, вообще невозможно сделать вывод о типах данных заранее. Если у вас есть функция max(x, y)
, и вы хотите скомпилировать ее с помощью собственного кода, вам нужно знать, какие возможные типы для x
и y
, и скомпилировать другую версию для каждой комбинации. Это может быть проблемой. Теперь вы можете ограничить некоторые функции, чтобы сделать такое вывод возможным, и там вы получите RPython.
Таким образом, программа питона может быть собрана, но это трудно сделать заранее и целиком.
Вот почему есть PyPy! PyPy - это JIT compiler. Вместо того, чтобы вызывать, он запускает код и анализирует его во время его запуска. Вот почему он оптимизирует только петли.Вот как это работает (очень грубо):
- PyPy позволяет бежать петлю на время, не мешая, при сборе данных о его потоке (в настоящее время на 1000 итераций)
- На основе собранных типов данных и потока, оптимизированных ассемблерный код генерируется и компилируется.
- «Охранники» установлены, чтобы проверить, соответствует ли фактический поток программы прогнозируемому.
- Исходный код выполняется до тех пор, пока не загорится защитный огонь или концы петли.
Кроме того, при разработке PyPy разработчики создали RPython, который является подмножеством Python, который, по сути, может быть полностью и статически скомпилирован. Они достигли этого, главным образом, путем принудительного раннего связывания. Например, если у вас есть переменная, которая является целым числом, вы не можете переназначить ее как символ позже в строке. Кроме того, вы не можете смешивать разные типы данных в списках или других контейнерах и т. Д.
Вам нужно было бы точно определить, что вы подразумеваете под «полностью скомпилированным». –
Он * может * быть статически скомпилирован в машинный код, но для этого необходимо, чтобы виртуальная машина python была помещена в результирующий двоичный файл. –
мой вопрос - почему. – Aristides