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


190

З мого розуміння:

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

Складено мовою є мовою високого рівня, код якого спочатку перетворюються в машинний код компілятором (програма , яка перетворює мову високого рівня в машинний код) , а потім виконується виконавцем (інша програма для виконання коду).

Виправте мене, якщо мої визначення неправильні.

Тепер, повертаючись до Python, я трохи збентежений з цього приводу. Скрізь ви дізнаєтесь, що Python - це інтерпретована мова, але вона інтерпретується як деякий проміжний код (наприклад, байт-код або IL), а не машинний код. То яка програма потім виконує код чату? Будь ласка, допоможіть мені зрозуміти, як обробляється та запускається сценарій Python.



2
Python створює файли .pyc (так званий byecode) кожного разу, коли імпортується бібліотека. Байт-код AFAIK може прискорити завантаження лише не час виконання.
Джесвін Хосе

2
@aitchnyu: Кешування байтового коду у .pyc файлах дійсно прискорює завантаження, але лише тому, що код Python компілюється в байт-код перед виконанням. Хоча я не думаю, що це було випробувано спеціально з Python, інші мовні реалізації показують, що байт-код дійсно простіше інтерпретувати ефективно, ніж звичайний AST або, що ще гірше, нерозбірливий вихідний код. Наприклад, старі версії Ruby інтерпретувались з AST, і AFAIK трохи перевищив новіші версії, які збираються в байт-код.

Ви не хочете звучати грубо, але хіба що я мав на увазі (але не так поінформований, як ви)?
Джесвін Хосе

1
@aitchnyu: Я не знаю, що ти мав на увазі. Я знаю лише, що ваш коментар був невірним, але він надав хорошу нагоду для деякої базової інформації, чому він тільки прискорює час завантаження, тому я вирішив додати цю інформацію. Жодного правопорушення не мається на увазі чи брали :)

Відповіді:


232

По-перше, інтерпретоване / складене - це не властивість мови, а властивість реалізації. Для більшості мов більшість, якщо не всі реалізації підпадають під одну категорію, тому можна зберегти кілька слів, які говорять про те, що мова також інтерпретується / компілюється, але це все-таки важлива відмінність як тому, що вона сприяє розумінню, так і тому, що є досить багато мов із зручними реалізаціями обох типів (переважно в царині функціональних мов, див. 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 .


2
Гаразд, це означає, що сценарій python спочатку компілюється в байт-код, а потім його реалізує інтерпретатор, як CPython, Jython або IronPython і т.д.
Pankaj Upadhyay

19
Ні, він компілюється в байт-код, а потім байт-код виконується відповідним VM. CPython є і компілятором, і VM, але Jython і IronPython - лише компілятор.
Ігнасіо Васкес-Абрамс

1
@Igacio: Я не маю великого досвіду роботи з IronPython / Jython, але чи принаймні Jython не забезпечує шар, що нагадує інтерпретатора? Я не вірю, що спробувати перетворити Python на статичний тип байт-коду JVM. І все-таки хороша думка щодо того, що компілятор та інтерпретатор є частиною одного пакету.

2
+1 "... властивість реалізації". Я сам би сказав "це дозволяє інтерактивну оболонку"
Jesvin Jose Jose

2
@delnan: Що ж, Jython виступає свого роду посередником між мовою Python та Java VM, але він компілює в байт-код Java.
Ігнасіо Васкес-Абрамс

34

Процесор справді може зрозуміти лише машинний код. Для інтерпретованих програм кінцевою метою перекладача є "інтерпретація" програмного коду в машинний код. Однак зазвичай сучасна інтерпретована мова не тлумачить людський код безпосередньо, оскільки він занадто неефективний.

Інтерпретатор Python спочатку зчитує людський код і оптимізує його до деякого проміжного коду, перш ніж інтерпретувати його в машинний код. Ось чому вам завжди потрібна інша програма для запуску сценарію Python, на відміну від C ++, де ви можете безпосередньо запустити скомпільований виконуваний код. Наприклад, c:\Python27\python.exeабо /usr/bin/python.


11
Мені подобається пункт про те, що "потрібна інша програма для запуску [її]". Це допомогло прояснити деякі мої думки.
Метт

так python.exe спочатку оптимізує код, а потім інтерпретує його?
Корай Тугай

@KorayTugay, коли python.exe надається текстовий вихідний код, читабельний людиною, він спочатку створює оптимізований байт-код, а потім інтерпретує це (як ви говорите); однак, коли вже є файл байтового коду (попередньо складений), він не повинен робити перший крок, що економить деякий час.
GordonBGood

31

Відповідь залежить від того, яка реалізація python використовується. Якщо ви використовуєте, скажімо, CPython (Стандартна реалізація python) або Jython (Цільова для інтеграції з мовою програмування java), її спочатку переводять у байт-код , і залежно від реалізації python, який ви використовуєте, цей код буде спрямований на відповідний віртуальна машина для інтерпретації . PVM (віртуальна машина Python) для CPython та JVM (віртуальна машина Java) для Jython.

Але скажемо, що ви використовуєте PyPy, що є ще однією стандартною реалізацією CPython. Він використовуватиме компілятор Just-in-Time .


Під час перекладу на байт-код йому потрібен компілятор, який це?
RICKY

Pypy - це реалізація Python , а не реалізація "CPython". Насправді Pypy є альтернативою CPython ( pypy.org/features.html ).
Джорджіо

13

Згідно з офіційним веб-сайтом Python, це мова з інтерпретацією.

https://www.python.org/doc/essays/blurb/

Python - інтерпретована, об'єктно-орієнтована мова програмування високого рівня ...

...

Оскільки немає кроку компіляції ...

...

Інтерпретатор Python та широка стандартна бібліотека доступні ...

...

Натомість, коли перекладач виявляє помилку, він створює виняток. Коли програма не вловлює виняток, інтерпретатор виводить слід стека.


7

Так, це і компільована, і інтерпретована мова. Тоді чому ми взагалі називаємо це інтерпретованою мовою?

Подивіться, як це складено та інтерпретується?

Перш за все, я хочу сказати, що вам більше сподобається моя відповідь, якщо ви з світу Java.

У Java вихідний код спочатку перетворюється в байтний код через компілятор javac, потім спрямовується в JVM (відповідальний за генерування власного коду з метою виконання). Тепер я хочу показати вам, що ми називаємо Java як скомпільовану мову, тому що ми бачимо, що вона дійсно компілює вихідний код і дає файл .class (нічого, крім байт-коду) через:

javac Hello.java -------> створює файл Hello.class

java Привіт --------> Напрям байт-коду до JVM для виконання

Те ж саме відбувається і з python, тобто спочатку вихідний код перетворюється в байт-код через компілятор, потім спрямовується до PVM (відповідальний за генерування власного коду з метою виконання). Тепер я хочу вам показати, що ми зазвичай називаємо Python як інтерпретовану мову, оскільки компіляція відбувається поза сценою і коли ми запускаємо код python через:

python Hello.py -------> безпосередньо виправдовує код, і ми можемо побачити вихід, що підтверджується, що код синтаксично правильний

@ python Hello.py, схоже, це безпосередньо виконується, але насправді спочатку генерується байт-код, який інтерпретується інтерпретатором, щоб створити власний код для виконання.

CPython - бере на себе відповідальність як за складання, так і за інтерпретацію.

Подивіться на рядки нижче, якщо вам потрібно детальніше :

Як я вже згадував, CPython компілює вихідний код, але фактична компіляція відбувається за допомогою cython, то інтерпретація відбувається за допомогою CPython

Тепер поговоримо трохи про роль компілятора Just-In-Time у Java та Python

У JVM існує інтерпретатор Java, який інтерпретує рядок байт-коду для отримання власного машинного коду з метою виконання, але коли байт-код Java виконується інтерпретатором, виконання завжди буде повільнішим. То яке рішення? рішення - компілятор Just-In-Time, який створює нативний код, який можна виконати набагато швидше, ніж це можна було б інтерпретувати. Деякі виробники JVM використовують інтерпретатор Java, а деякі використовують компілятор Just-in-Time . Довідка: натисніть тут

У python для обходу інтерпретатора для досягнення швидкого виконання використовуйте іншу реалізацію python ( PyPy ) замість CPython . натисніть тут для іншої реалізації python, включаючи PyPy .


6

Якщо (Ви знаєте Java) {

код Python перетворений в байт-код, як це робить Java.
Цей байт-код знову виконується кожного разу, коли ви намагаєтесь отримати доступ до нього.

} else {

Python-код спочатку переноситься на щось, що називається байт-кодом,
який досить близький до машинної мови, але не є фактичним машинним кодом,
тому кожен раз, коли ми отримуємо доступ або запускаємо його, цей байт-код виконується знову

}


2

Майже можна сказати, що Python - це інтерпретована мова. Але ми використовуємо частину процесу компіляції часу в python для перетворення повного вихідного коду в байт-код, наприклад, мову java.


1

Для новачків

Перед запуском програми Python автоматично компілює ваш сценарій до зібраного коду, так званого байтового коду.

Запуск сценарію не вважається імпортом, і жоден .pyc не буде створений.

Наприклад, якщо у вас є файл скрипта abc.py, який імпортує інший модуль xyz.py, коли ви запускаєте abc.py, xyz.pyc буде створений з моменту імпорту xyz, але файл abc.pyc не буде створений після abc. py не імпортується.


1

Це велика плутанина для людей, які почали працювати над пітоном, і відповіді тут трохи важко зрозуміти, тому я полегшу.

Коли ми доручаємо Python запустити наш скрипт, є кілька кроків, які виконує Python, перш ніж наш код насправді почне стискати:

  • Він компілюється в байт-код.
  • Потім він перенаправляється на віртуальну машину.

Коли ми виконуємо вихідний код, Python компілює його в байт-код. Компіляція - це етап перекладу, а байт-код - це низькорівневе платформене представлення вихідного коду. Зауважте, що байт-код Python не є двійковим машинним кодом (наприклад, інструкція для мікросхеми Intel).

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

Отже, наступного разу, коли ми запустимо ту саму програму, Python завантажить файл .pyc і пропустить етап компіляції, якщо він не був змінений. Python автоматично перевіряє часові позначки вихідних та байтових файлів коду, щоб знати, коли він повинен перекомпілюватись. Якщо ми збережемо вихідний код, байтовий код автоматично створюється знову при наступному запуску програми.

Якщо Python не може записати файли коду байтів на нашу машину, наша програма все ще працює. Код байту генерується в пам'яті і просто викидається при виході з програми. Але оскільки файли .pyc прискорюють час запуску, ми можемо захотіти переконатися, що вони написані для великих програм.

Давайте підведемо підсумки, що відбувається за лаштунками. Коли Python виконує програму, Python зчитує .py в пам'ять і аналізує її, щоб отримати байт-код, а потім продовжує виконання. Для кожного модуля, який імпортується програмою, Python спочатку перевіряє, чи є попередньо скомпільована версія байт-коду у форматі .pyo чи .pyc, що має часову позначку, що відповідає її файлу .py. Python використовує версію байт-коду, якщо така є. В іншому випадку він аналізує .py-файл модуля, зберігає його у .pyc-файл та використовує щойно створений байт-код.

Байтові файли коду також є одним із способів доставки кодів Python. Python все одно запустить програму, якщо всі файли є файли.pyc, навіть якщо оригінальних вихідних файлів .py там немає.

Віртуальна машина Python (PVM)

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


0

Код python, який ви пишете, компілюється в байт-код python, який створює файл із розширенням .pyc. Якщо компілюється, знову питання, чому б не складена мова.

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

Повертаючись до процесу виконання, ваш байт-код, присутній у файлі pyc, створеному на етапі компіляції, потім виконується відповідними віртуальними машинами, у нашому випадку CPython VM Штамп часу (називається магічним числом) використовується для перевірки того, чи є. Файл py змінюється чи ні, залежно від того, що створюється новий файл pyc. Якщо pyc є поточним кодом, він просто пропускає етап компіляції.


0

Python (інтерпретатор) буде складено .

Доказ. Він навіть не компілює ваш код, якщо він містить синтаксичну помилку .

Приклад 1:

print("This should print") 
a = 9/0 

Вихід:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

Код успішно компілюється. Перший рядок виконується ( print) кидає другий рядок ZeroDivisionError(помилка часу запуску).

Приклад 2:

print("This should not print")
/0         

Вихід:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

Висновок : Якщо ваш код-код SyntaxErrorне містить нічого, він не буде виконаний, оскільки компіляція не вдається.

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