Интерпретируется ли Python или компилируется, или и то, и другое?

190

Из моего понимания:

Интерпретировать язык бег на языке высокого уровня и выполняются переводчиком (программа , которая преобразует язык высокого уровня в машинный код , а затем выполнение) на ходе; он обрабатывает программу постепенно.

Составлен языком является языком высокого уровня, код которого сначала преобразуются в машинный код компилятором (программа , которая преобразует язык высокого уровня в машинный код) , а затем выполняется исполнителем (другая программа для выполнения кода).

Поправь меня, если мои определения неверны.

Возвращаясь к Python, я немного растерялся по этому поводу. Везде вы узнаете, что Python - это интерпретируемый язык, но он интерпретируется как некоторый промежуточный код (например, байт-код или IL), а не как машинный код. Так, какая программа тогда выполняет код IM? Пожалуйста, помогите мне понять, как обрабатывается и выполняется скрипт Python.

Панкадж Упадхяй
источник
2
Python создает файлы .pyc (так называемый byecode) всякий раз, когда библиотека импортируется. AFAIK байт-код может только ускорить время загрузки, но не время выполнения.
Джесвин Хосе
2
@aitchnyu: кэширование байт-кода в файлах .pyc действительно только ускоряет загрузку, но только потому, что код Python компилируется в байт-код перед выполнением в любом случае. Хотя я не думаю, что это было сделано специально с Python, другие языковые реализации показывают, что байт-код действительно проще интерпретировать эффективно, чем простой AST или, что еще хуже, неразобранный исходный код. Например, более старые версии Ruby интерпретировались из AST, и AFAIK значительно превосходил более новые версии, которые компилируются в байт-код.
Не хочу показаться грубым, но разве это не то, что я имел в виду (но не настолько информирован, как ты)?
Джесвин Хосе
1
@aitchnyu: я не знаю, что ты имел в виду. Я только знаю, что ваш комментарий не был неправильным, но предоставил хорошую возможность для некоторой справочной информации, почему он только ускоряет время загрузки, поэтому я решил добавить эту информацию. Без обид подразумевается или принимается :)

Ответы:

233

Во-первых, интерпретируемый / скомпилированный является не свойством языка, а свойством реализации. Для большинства языков большинство, если не все реализации, попадают в одну категорию, поэтому можно было бы сохранить несколько слов, говоря, что язык также интерпретируется / компилируется, но это по-прежнему важное различие, как потому, что оно помогает пониманию, так и потому, что существует довольно много языков. с полезными реализациями обоих видов (в основном в области функциональных языков, см. Haskell и ML). Кроме того, существуют интерпретаторы C и проекты, которые пытаются скомпилировать подмножество Python для кода C или C ++ (и впоследствии для машинного кода).

Во-вторых, компиляция не ограничивается преждевременной компиляцией с собственным машинным кодом. В общем, компилятор - это программа, которая преобразует программу на одном языке программирования в программу на другом языке программирования (возможно, вы даже можете иметь компилятор с тем же языком ввода и вывода, если применяются значительные преобразования). А JIT-компиляторы компилируются в собственный машинный код во время выполнения , что может дать скорость, очень близкую или даже лучшую, чем опережающая компиляция (в зависимости от эталона и качества сравниваемых реализаций).

Но чтобы перестать придираться и ответить на вопрос, который вы хотели задать: Практически (читай: используя несколько популярную и зрелую реализацию), Python компилируется . Не скомпилирован в машинный код досрочно (то есть «скомпилирован» по ограниченному и неправильному, но увы общему определению), «только» скомпилирован в байт-код , но это все же компиляция, по крайней мере, с некоторыми из преимуществ. Например, оператор a = b.c()компилируется в поток байтов, который, когда он «разобран», выглядит примерно так load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). Это упрощение, на самом деле оно менее читабельно и немного более низкого уровня - вы можете поэкспериментировать со стандартным disмодулем библиотеки и посмотреть, как выглядит реальная сделка.

Этот байт-код либо интерпретируется (обратите внимание, что есть разница, как в теории, так и в практической производительности, между интерпретацией напрямую и сначала компиляцией в некоторое промежуточное представление и интерпретацию этого), как в случае эталонной реализации (CPython), либо как интерпретацией, так и компилированием в оптимизированный машинный код во время выполнения, как с PyPy .

jsmedmar
источник
2
Хорошо, это означает, что скрипт Python сначала компилируется в байт-код, а затем он реализуется интерпретатором, таким как CPython, Jython или IronPython и т. Д.
Pankaj Upadhyay
19
Нет, он компилируется в байт-код, а затем байт-код выполняется соответствующей виртуальной машиной. CPython является одновременно и компилятором, и виртуальной машиной, но Jython и IronPython являются всего лишь компилятором.
Игнасио Васкес-Абрамс
1
@Igacio: У меня нет большого опыта работы с IronPython / Jython, но разве Jython не предоставляет слой, похожий на интерпретатор? Я не верю, что можно попытаться превратить Python в байт-код JVM со статической типизацией. Тем не менее, хороший момент в том, что компилятор и интерпретатор являются частью одного пакета.
2
+1 "... свойство реализации". Я сам сказал бы, что «это позволяет создавать интерактивную оболочку»
Джесвин Хосе
2
@delnan: Ну, Jython действует как своего рода посредник между языком Python и Java VM, но компилируется в байт-код Java.
Игнасио Васкес-Абрамс