Czy Python jest interpretowany lub kompilowany?

76

To tylko zastanawiam się, kiedy czytałem o językach interpretowanych i kompilowanych.

Ruby jest bez wątpienia językiem interpretowanym, ponieważ kod źródłowy jest przetwarzany przez interpretera w punkcie wykonania.
Przeciwnie, C jest językiem kompilowanym, ponieważ najpierw należy skompilować kod źródłowy zgodnie z maszyną, a następnie wykonać. Wynikiem tego jest znacznie szybsze wykonanie.

Teraz nadchodzi do Pythona :

  • Kod Pythona ( somefile.py ) po zaimportowaniu tworzy plik ( somefile.pyc ) w tym samym katalogu. Powiedzmy, że import odbywa się w powłoce Pythona lub module django. Po zaimportowaniu zmieniam nieco kod i ponownie uruchamiam zaimportowane funkcje, aby stwierdzić, że nadal działa stary kod. Sugeruje to, że pliki * .pyc są skompilowanymi plikami Pythona podobnymi do plików wykonywalnych utworzonych po kompilacji pliku C, chociaż nie mogę bezpośrednio wykonać pliku * .pyc.
  • Gdy plik python (somefile.py) jest wykonywany bezpośrednio (./somefile.py lub python somefile.py), plik .pyc nie jest tworzony, a kod jest wykonywany, co wskazuje na interpretowane zachowanie.

Sugerują to, że kod Pythona jest kompilowany za każdym razem, gdy jest importowany w nowym procesie w celu utworzenia pliku .pyc, który jest interpretowany podczas bezpośredniego wykonywania.

Więc jaki rodzaj języka powinienem uznać za? Zinterpretowany czy skompilowany? Jaka jest jego skuteczność w porównaniu do języków interpretowanych i kompilowanych?

Zgodnie ze stroną języków interpretowanych wiki jest wymieniony jako język skompilowany do wirtualnego kodu maszyny, co to oznacza?

Crodjer
źródło
1
Kiedy pojawiają się wątpliwości, czy Ruby jest językiem tłumaczonym? Kiedy jest skompilowany. :) macruby.org
mipadi
8
Warto zauważyć, że żaden współczesny język nie jest interpretowany w ścisłym tego słowa znaczeniu. Praktycznie wszystkie z nich kompilują się do kodu bajtowego.
Winston Ewert,
@Winston Ewert: bravo! Applesoft Basic (w latach 80-tych) został skompilowany z użyciem kodu bajtowego. „nowoczesny” w tym przypadku oznacza każdy interpretowany język w żywej pamięci, a jedynym możliwym wyjątkiem są niektóre podstawowe implementacje Dartmouth Basic.
S.Lott,
6
>> Przeciwnie, C to skompilowany język << root.cern.ch/drupal/content/cint
igouy
3
@ S.Lott: Wywoływanie procesu tokenizacji, który wykonali interpreciści Applesoft i BASIC z lat 80., „kompilacją kodu bajtowego” jest więcej niż trochę nieszczęsne. Tak, kod programu wprowadzony przez użytkownika był przechowywany w pamięci w formie skompresowanej, jeden bajt na zarezerwowane słowo, ale nic więcej nie zostało zrobione do momentu wpisania RUN. To było tak, jakbyś miał kompilator, który wykonał krok leksykalny, a następnie wypisał strumień tokenów, które trzeba było ponownie przeanalizować przy każdym uruchomieniu programu. javacZupełnie nie tak jak nowoczesna kompilacja kodu bajtowego wykonywana przez powiedzmy , która obejmuje leksykację, parsowanie i optymalizację.
dodgethesteamroller

Odpowiedzi:

80

Warto zauważyć, że języki nie są interpretowane ani kompilowane, ale implementacje językowe interpretują lub kompilują kod. Zauważyłeś, że Ruby jest „językiem interpretowanym”, ale możesz skompilować Ruby à la MacRuby , więc nie zawsze jest to język interpretowany.

Prawie każda implementacja Pythona składa się z interpretera (a nie kompilatora). Te .pycpliki można zobaczyć to kod bajtowy dla maszyny wirtualnej Pythona (podobny do Javy .classplików). Nie są takie same jak kod maszynowy generowany przez kompilator C dla natywnej architektury maszynowej. Jednak niektóre implementacje Pythona składają się z kompilatora just-in-time , który skompiluje bajtowy kod Pythona w natywny kod maszynowy.

(Mówię „prawie każdy”, ponieważ nie znam żadnych natywnych kompilatorów maszyn dla Pythona, ale nie chcę twierdzić, że nigdzie nie istnieją).

mipadi
źródło
W zależności od twojej definicji istnieją natywne kompilatory maszynowe dla Pythona. Niektóre kompilują tylko podzbiór Pythona. Inni implementują cały Python, ale używają API Pythona do wykonywania operacji, których nie może wykonać w C.
Winston Ewert
Myślę, że tak naprawdę opisujesz, że Python jest albo tym, co nazwałbym „częściowo skompilowanym”, albo może być w pełni skompilowany. Przez częściowo skompilowany rozumiem, że ponieważ jest on zwykle kompilowany do pliku .pyc „języka pośredniego”, który jest używany przez maszynę wirtualną Pythona, zwykle jest uruchamiany z tej formy „częściowo skompilowanej”, która generalnie sprawia, że ​​kod jest szybszy niż prosta interpretacja interpretowanego kodu w czasie wykonywania. Co ciekawe, częściowo skompilowany kod może czasem być szybszy niż kod skompilowany natywnie (np. C # jest generalnie szybszy niż C ++).
Chris Halcrow,
5
Cython kompiluje kod Pythona do C, dzięki czemu można go skompilować jako obiekt współdzielony.
greyfade
W ten sposób rozróżnianie kodu bajtowego i kodu maszynowego jest dość arbitralne. Java jest kompilowana: kompilator javac tworzy pliki klas zawierające instrukcje niskiego poziomu, które mogą być wykonywane na maszynie wirtualnej (np. Hotspot) lub bezpośrednio przez sprzęt (np. Na procesorach ARM z rozszerzeniem Jazelle). O ile mi wiadomo, nie ma technicznego powodu, aby podobna architektura procesorów nie mogła zostać zaprojektowana do bezpośredniego wykonywania instrukcji python vm.
Jules
@Jules Przypadkowo, kod Jython jest faktycznie kompilowany do plików .class, które moim zdaniem są ponownie używane, dopóki nie zmodyfikujesz źródła py.
JimmyJames
35

Python zostanie objęty interpretowanym kodem bajtowym. .pykod źródłowy jest najpierw kompilowany do kodu bajtowego jako .pyc. Ten bajtowy kod można interpretować (oficjalny CPython) lub skompilować JIT (PyPy). Kod źródłowy Pythona ( .py) można skompilować do innego kodu bajtowego, takiego jak IronPython (.Net) lub Jython (JVM). Istnieje wiele implementacji języka Python. Oficjalny to interpretowany kod bajtowy. Istnieją również implementacje skompilowane z kodem bajtowym JIT.

W celu porównania prędkości różnych implementacji języków możesz wypróbować tutaj .

aufather
źródło
dzięki za informacje. Według testów wydajności Pythona jest znacznie niższa!
autor
1
Link, który podałem bardzo wyraźnie, stwierdza, że ​​są one wadliwymi punktami odniesienia dla implementacji językowych . Python nie powinien być twoim wyborem języka, jeśli martwisz się zbytnio wydajnością wykonywania. Jeśli nadal chcesz porównywać, porównaj podobne języki. Bajt interpretowany oficjalny CPython jest porównywalny lub szybszy niż Ruby skompilowany przez JIT.
sierpień
1
@ jase21 - „Moje plany na 2006 r. polegają na przeniesieniu technik zaimplementowanych w Psyco do PyPy. PyPy pozwoli nam zbudować bardziej elastyczny specjalistę JIT, łatwiejszy do eksperymentowania i bez konieczności dostosowywania się do ewolucji język Python ”. psyco.sourceforge.net/introduction.html
igouy
1
@ jase21 - „sprawia, że ​​kody Pythona działają szybciej niż części licznika C” - Czy mamy po prostu uwierzyć na to?
igouy
3
Link w odpowiedzi jest zepsuty.
Basilevs
11

Kompilacja vs. interpretacja może być pomocna w niektórych kontekstach, ale zastosowana w sensie technicznym jest fałszywą dychotomią.

Kompilator (w najszerszym tego słowa znaczeniu) jest tłumaczem . Tłumaczy program A na program B i do wykonania w przyszłości za pomocą maszyny M.

Tłumacz (w najszerszym tego słowa znaczeniu) jest wykonawcą . Jest to maszyna M, która wykonuje program A. Chociaż zwykle wykluczamy z tej definicji maszyny fizyczne (lub maszyny niefizyczne, które działają tak samo jak maszyny fizyczne). Ale z teoretycznego punktu widzenia to rozróżnienie jest nieco arbitralne.


Na przykład weź re.compile. „Kompiluje” wyrażenie regularne do formy pośredniej, a ta forma pośrednia jest interpretowana / oceniana / wykonywana.


Ostatecznie zależy to od poziomu abstrakcji, o którym mówisz i na czym ci zależy. Ludzie mówią „skompilowane” lub „zinterpretowane” jako ogólne opisy najciekawszych części procesu, ale tak naprawdę większość programów jest kompilowana (tłumaczona) i interpretowana (wykonywana) w taki czy inny sposób.

CPython (najpopularniejsza implementacja języka Python) jest najbardziej interesująca do wykonywania kodu. Tak więc CPython byłby zwykle opisywany jako interpretowany. Chociaż jest to luźna etykieta.

Paul Draper
źródło
7

Virtual Machine Code to bardziej kompaktowa wersja oryginalnego kodu źródłowego (kod bajtowy). Nadal musi być interpretowany przez maszynę wirtualną, ponieważ nie jest to kod maszynowy. Jednak parsowanie jest łatwiejsze i szybsze niż oryginalny kod napisany przez człowieka.

Niektóre maszyny wirtualne generują kod maszynowy podczas pierwszej interpretacji kodu maszyny wirtualnej (kompilacja just in time - JIT). Poniższe wywołania wykorzystają bezpośrednio ten kod maszynowy, co prowadzi do szybszego wykonania.

O ile wiem Ruby> = 1.9 używa również maszyny wirtualnej takiej jak Python.

LennyProgrammers
źródło
5

Środowisko wykonawcze Python uruchamia niestandardowy kod obiektowy (kod bajtowy) na maszynie wirtualnej.

Proces kompilacji konwertuje kod źródłowy na kod obiektowy.

Aby przyspieszyć, kod obiektowy (lub kod bajtowy, jeśli wolisz) jest przechowywany na dysku, dzięki czemu można go ponownie użyć przy następnym uruchomieniu programu.

ykombinator
źródło