Зачем Python нужен и компилятор, и интерпретатор?

9

Я могу понять тот факт, что Java нуждается как в компиляторе, так и в интерпретаторе. Он компилирует исходный код в байт-код, а затем виртуальная машина (в Windows, в Linux, на Android и т. Д.) Преобразует этот байт-код в машинный код для текущей архитектуры.

Но зачем Python нужен и компилятор, и интерпретатор? Поскольку Python не зависит от платформы, почему бы просто не использовать интерпретацию? Насколько я знаю, вы не можете выполнить программу Python (скомпилированную в байт-код) на любой машине Windows или Linux без изменений. Или я не прав?

ARIS
источник
Вы можете ошибаться. Если вы используете Lua вместо Python, вы ошибаетесь.
Василий Старынкевич

Ответы:

13

Насколько я знаю, вы не можете выполнить программу Python (скомпилированную в байт-код) на каждой машине, например, в Windows или в Linux без изменений.

Вы не правы. Байт-код Python является кроссплатформенным. См. Байт-код Python зависит от версии? Это зависит от платформы? Переполнение стека. Тем не менее, он не совместим между версиями. Python 2.6 не может выполнять файлы Python 2.5. Таким образом, в то время как кроссплатформенность, это не очень полезно как формат распространения.

Но зачем Python нужен и компилятор, и интерпретатор?

Скорость. Строгая интерпретация идет медленно. Практически каждый «интерпретируемый» язык фактически компилирует исходный код в своего рода внутреннее представление, чтобы ему не приходилось многократно анализировать код. В случае с Python это внутреннее представление сохраняется на диск, чтобы он мог пропустить процесс синтаксического анализа / компиляции в следующий раз, когда ему понадобится код.

Уинстон Эверт
источник
7

Я могу понять тот факт, что Java нуждается как в компиляторе, так и в интерпретаторе.

Это не так. В Спецификации языка Java нет ничего, что говорило бы о том, что Java должен иметь компилятор. В Спецификации языка Java также нет ничего, что говорило бы о том, что Java должен иметь интерпретатора.

Использовать ли интерпретатор, компилятор или их комбинацию, полностью оставлено на усмотрение разработчика.

На самом деле, есть реализации Java , которые прямо компилировать в машинный код, например, GNU Compiler для Java gcj. Технически говоря, Java OpenJDK Java-компилятор также компилируется в машинный код, в частности, в байтовый код JVM. Теперь, вы можете сказать, подождите минуту, это не машинный код! Но существуют программные интерпретаторы для машинного кода x86, и есть аппаратные процессоры, которые могут выполнять байт-код JVM, так что же делает один «родной», а другой - нет?

Обратите внимание, что байт-код JVM находится вне спецификации языка Java, как это делает машинный код x86.

а затем виртуальная машина (в Windows, в Linux, в Android и т. д.) преобразует этот байт-код в машинный код для текущей архитектуры.

Опять же, это зависит только от разработчика.

Оригинальная Sun JVM никогда не переводила, она всегда интерпретировалась. Текущая версия Oracle OpenJDK JVM интерпретирует, и только те части, которые выполняются часто, компилируются. Maxine Research VM всегда JIT компилируется. Реализация Excelsior.JET компилируется один раз, заблаговременно. JVM IKVM.NET компилируется в байт-код CIL. Android Runtime компилируется заранее, один раз, во время установки. (Кроме того, среда выполнения Android не понимает байт-код JVM, она использует байт-код Dalvik, который является совершенно другим языком.)

Но зачем Python нужен и компилятор, и интерпретатор?

Опять же, это не так. В Спецификации языка Python нет ничего, что говорило бы о том, что Python должен иметь компилятор. В Спецификации языка Python также нет ничего, что говорило бы о том, что Python должен иметь интерпретатора.

Обратите внимание, что на самом деле Python никогда не интерпретируется. Все существующие реализации Python всегда компилируют Python на другой язык. Этот язык может или не может, в свою очередь, быть интерпретирован, но этот язык отличается от языка Python. Python не интерпретируется.

почему бы просто не использовать интерпретацию?

Потому что Python не предназначен для легкой интерпретации машинами. Это разработано, чтобы быть легко интерпретируемым людьми. Ото, CPython байт - код, будет разработан , чтобы быть легко интерпретировать с помощью машин. Таким образом, имеет смысл писать код на языке, предназначенном для людей, и интерпретировать на языке, предназначенном для машин, и для того, чтобы переходить от одного к другому, вы должны скомпилировать.

Насколько я знаю, вы не можете выполнить программу Python (скомпилированную в байт-код) на любой машине Windows или Linux без изменений.

Да, ты можешь. Виртуальная машина CPython доступна как для Windows, так и для Linux, как и PyPy, Jython и IronPython.


Языки не должны быть скомпилированы или интерпретированы. Языки просто есть . На самом деле язык может прекрасно существовать без какого-либо интерпретатора или компилятора! Например, Plankalkül Конрада Цузе, который он разработал в 1930-х годах, так и не был реализован при его жизни. Вы все еще могли бы писать программы в нем, вы могли анализировать эти программы, рассуждать о них, доказывать свойства о них ... вы просто не могли их выполнять. (Ну, на самом деле, даже это неправильно: вы, конечно, можете запустить их в своей голове или ручкой и бумагой.)

Теперь любая конкретная реализация языка может использовать компилятор (или даже несколько компиляторов), интерпретатор или любую комбинацию. Но это черта реализации , а не язык. Каждый язык может быть реализован с помощью компилятора, и каждый язык может быть реализован с помощью интерпретатора.

Обратите внимание, однако, что вы не можете запустить программу без переводчика. Компилятор просто переводит программу с одного языка на другой. Но это все. Теперь у вас одна и та же программа, просто на другом языке. Только способ действительно получить результат этой программы заключается в интерпретации его. Иногда язык является чрезвычайно простым двоичным машинным языком, и интерпретатор на самом деле жестко запрограммирован в силиконе (и мы называем это «CPU»), но это все еще интерпретация.

Вас также может заинтересовать этот мой ответ, который объясняет различия и различные способы объединения интерпретаторов, JIT-компиляторов и AOT-компиляторов, и этот ответ касается различий между AOT-компилятором и JIT-компилятором .

Йорг Миттаг
источник
3
Ответы, которые проводят большую часть своего времени, будучи педантичным, вместо того, чтобы отвечать на вопрос, меня огорчают.
Уинстон Эверт
3

Это правда, что байт-код не подходит в качестве формата распространения, но это не значит, что он бесполезен. Помимо улучшения времени запуска на данном компьютере, после первого запуска интерпретация байт-кода также намного проще, чем интерпретация AST или, не дай бог, интерпретация построчно.

Байт-код - это более низкоуровневое, более регулярное, более компактное (как семантически, так и с точки зрения размещения в памяти) представление кода. Порядок операций уже прописан, имена локальных переменных были преобразованы в более простую форму (целочисленные индексы). Нет сложного синтаксиса для подражания, просто одна простая инструкция за другой. Кроме того, требуется меньшее состояние: для построчной интерпретации вам, в основном, необходимо хранить целый синтаксический анализатор, а интерпретатор AST взрывает стек вызовов своим обходом дерева, тогда как интерпретатору байт-кода просто нужен небольшой стек для временных значений и местные жители.

Эти и другие факторы способствуют тому, чтобы интерпретаторы байт-кода значительно быстрее, чем другие интерпретаторы.


источник