Чи інтерпретується або компілюється Python?


76

Це просто цікаво, що я мав, читаючи про інтерпретовані та складені мови.

Ruby , без сумніву, є інтерпретованою мовою, оскільки вихідний код обробляється інтерпретатором на місці виконання.
Навпаки, C - це компільована мова, оскільки спершу потрібно скласти вихідний код відповідно до машини, а потім виконати. Це призводить до набагато швидшого виконання.

Зараз підходимо до Python :

  • Код python ( somefile.py ) при імпорті створює файл ( somefile.pyc ) у тому самому каталозі. Скажімо, імпорт здійснюється в оболонці python або модулі django. Після імпорту я трохи змінюю код і знову виконую імпортні функції, щоб виявити, що він все ще працює зі старим кодом. Це говорить про те, що файли * .pyc - це компільовані файли python, схожі на виконуваний файл, створений після компіляції файлу C, хоча я не можу виконати файл * .pyc безпосередньо.
  • Коли файл python (somefile.py) виконується безпосередньо (./somefile.py або python somefile.py), не створюється файл .pyc і код виконується так, як свідчить про інтерпретовану поведінку.

Вони припускають, що код python компілюється кожного разу, коли він імпортується в новому процесі для створення .pyc, тоді як він інтерпретується при безпосередньому виконанні.

Отже, який тип мови я повинен вважати ним? Інтерпретовано чи складено? І як її ефективність порівнюється з інтерпретованими та складеними мовами?

Відповідно до сторінки Вікі- інтерпретовані мови , вона перерахована як мова, складена до віртуального машинного коду, що це означає?


1
Коли виникають сумніви щодо того, чи є Рубі інтерпретована мова? Коли вона складена. :) macruby.org
mipadi

8
Варто зазначити, що жодна сучасна мова не трактується в строгому значенні. Практично всі вони компілюються в байт-код.
Вінстон Еверт

@Winston Ewert: браво! Applesoft Basic (у 1980-х роках) був складений байт-код. "сучасний" в даному випадку означає, що кожна інтерпретована мова в живій пам'яті, єдиний можливий виняток - деякі рудиментарні реалізації Dartmouth Basic.
С.Лотт

6
>> Навпаки, C - мова, складена << root.cern.ch/drupal/content/cint
igouy

3
@ S.Lott: Викликати процес токенізації, який інтерпретатори Applesoft та 80-х BASIC робили "компіляцією байт-кодів", є більш ніж трохи непотрібним. Так, програмний код, введений користувачем, зберігався в пам’яті в стисненому вигляді, один байт на зарезервоване слово, але нічого не було зроблено за межами цього, поки ви не ввели RUN. Це було так, як якщо б у вас був компілятор, який робив крок лексінгу, а потім виводив потік лексем, який доводилося переробляти щоразу, коли програма запускалася. Зовсім не так, як сучасна компіляція байт-кодів, як це зроблено, скажімо javac, що включає в себе лексинг, аналіз та оптимізацію.
dodgethesteamroller

Відповіді:


80

Варто зазначити, що мови не інтерпретуються чи не компілюються, а скоріше мовні реалізації або інтерпретують, або компілюють код. Ви зазначали, що Ruby - це "інтерпретована мова", але ви можете скласти Ruby à la MacRuby , тому це не завжди інтерпретована мова.

Практично кожна реалізація Python складається з інтерпретатора (а не компілятора). Ці .pycфайли ви бачите байт - код для віртуальної машини Python ( по аналогії з Яви .classфайлів). Вони не збігаються з машинним кодом, сформованим компілятором С для нативного архітектури машини. Деякі реалізації Python, однак, складаються з щойно вкладеного компілятора, який буде компілювати байт-код Python у власний машинний код.

(Я кажу "майже кожен", тому що я не знаю жодного нативного компілятора машин для Python, але я не хочу стверджувати, що жодного не існує.)


Залежно від вашого визначення, існують власні компілятори машин для Python. Деякі складають лише підмножину python. Інші реалізують весь python, але використовують API python, щоб фактично виконувати операції, які він не може виконувати в C.
Winston Ewert

Я думаю, ви насправді описуєте, що Python - це те, що я б назвав «напівкомпільований», або насправді може бути повністю складений. Під напівкомпільованим я маю на увазі, що оскільки він зазвичай компілюється у файл «проміжної мови» .pyc, який використовується віртуальною машиною Python, він зазвичай запускається з цієї «напівкомпільованої» форми, яка, як правило, робить код швидшим, ніж звичайна інтерпретація інтерпретованого коду під час виконання. Цікаво, що напівкомпільований код іноді може бути швидшим, ніж первісно складений код (наприклад, C #, як правило, швидше, ніж C ++).
Кріс Халкроу

5
Cython компілює код Python на C, щоб його можна було скласти як спільний об'єкт.
greyfade

Розрізняти байт-код і машинний код таким чином досить умовно. Компілюється Java: компілятор javac виробляє файли класів, що містять інструкції низького рівня, які можуть виконуватися або у віртуальній машині (наприклад, гаряча точка), або безпосередньо апаратно (наприклад, на процесорах ARM з розширенням Jazelle). Наскільки я знаю, немає жодних технічних причин подібна архітектура процесора не могла бути розроблена для безпосереднього виконання інструкцій python vm.
Жуль

@Jules Навпаки, код Jython насправді компілюється у файли .class, які, на мою думку, використовуються повторно, поки ви не модифікуєте джерело py.
JimmyJames

35

Python потрапить під інтерпретований байт-код. .pyспочатку компілюється вихідний код у байт-код як .pyc. Цей байт-код можна інтерпретувати (офіційний CPython) або компілювати JIT (PyPy). Вихідний код Python ( .py) може бути скомпільований до різних байтових кодів, таких як IronPython (.Net) або Jython (JVM). Існує кілька реалізацій мови Python. Офіційний - інтерпретований байт-код. Існують також байт-коди JIT, складені реалізаціями.

Для порівняння швидкості різних мов можна спробувати тут .


ніж за показник. Відповідно до еталонів, ефективність пітона знижується!
crodjer

1
Посилання, яке я дав дуже чітко, стверджує, що це недосконалі орієнтири мовної реалізації . Python не повинен бути вашим вибором мови, якщо ви надто переживаєте про ефективність виконання. Якщо ви все ще хочете порівняти, порівняйте подібні мови. Байт-код, інтерпретований офіційним CPython, порівнянний або швидший, ніж JIT, складений Ruby.
аут

1
@ jase21 - "Мої плани на 2006 рік - перенести методи, реалізовані в Psyco, до PyPy. PyPy дозволить нам створити більш гнучкий спеціалізатор JIT, простіше експериментувати і без накладних витрат не дотримуватися синхронізації з еволюцією мова пітона ". psyco.sourceforge.net/introduction.html
igouy

1
@ jase21 - "змушує python-коди працювати швидше, ніж лічильники C" - Ми повинні просто взяти ваше слово за це?
igouy

3
Посилання у відповіді порушено.
Василевс

11

Складене та інтерпретоване може бути корисним у деяких контекстах, але якщо застосовуватись у технічному розумінні, це хибна дихотомія.

Укладач (у широкому розумінні) - це перекладач . Він переводить програму A в програму B і для подальшого виконання її за допомогою машини M.

Перекладач (у широкому сенсі) - виконавець . Це машина M, яка виконує програму А. Хоча ми зазвичай виключаємо із цього визначення фізичні машини (або нефізичні машини, які діють так само, як фізичні). Але з теоретичної точки зору це відмінність є дещо довільним.


Наприклад, візьміть re.compile. Він "компілює" регулярний вираз до проміжної форми, і ця проміжна форма інтерпретується / оцінюється / виконується.


Зрештою, це залежить від рівня абстракції, про який ви говорите, і про що ви дбаєте. Люди кажуть, що "складено" або "інтерпретується" як широкий опис найцікавіших частин процесу, але насправді більшість кожної програми складається так (інакше) та інтерпретується (виконується).

CPython (найпопулярніша реалізація мови Python) здебільшого цікавий для виконання коду. Отже, CPython, як правило, характеризується як інтерпретований. Хоча це вільна етикетка.


7

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

Деякі віртуальні машини генерують машинний код під час першої інтерпретації коду віртуальної машини (саме під час компіляції - JIT). Наступні виклики будуть використовувати цей машинний код безпосередньо, що призводить до швидшого виконання.

Наскільки я знаю, Ruby> = 1.9 також використовує віртуальну машину на зразок Python.


5

Під час виконання Python на віртуальній машині працює власний об'єктний код (байт-код).

Процес компіляції перетворює вихідний код в об'єктний код.

Для прискорення роботи об'єктний код (або байт-код, якщо ви бажаєте) зберігається на диску, тому його можна буде повторно використовувати при наступному запуску програми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.