Python è interpretato o compilato o entrambi?


190

Dalla mia comprensione:

Una lingua interpretata è una lingua di alto livello eseguita ed eseguita da un interprete (un programma che converte la lingua di alto livello in codice macchina e quindi in esecuzione) in movimento; elabora il programma un po 'alla volta.

Una lingua compilata è una lingua di alto livello il cui codice viene prima convertito in codice macchina da un compilatore (un programma che converte la lingua di alto livello in codice macchina) e quindi eseguito da un esecutore (un altro programma per l'esecuzione del codice).

Correggimi se le mie definizioni sono sbagliate.

Ora tornando a Python, sono un po 'confuso su questo. Ovunque apprendi che Python è un linguaggio interpretato, ma è interpretato da un codice intermedio (come byte-code o IL) e non dal codice macchina. Quindi quale programma esegue quindi il codice IM? Aiutatemi a capire come viene gestito ed eseguito uno script Python.



2
Python crea file .pyc (il cosiddetto byecode) ogni volta che viene importata una libreria. AFAIK il bytecode può solo accelerare i tempi di caricamento, non i tempi di esecuzione.
Jesvin Jose,

2
@aitchnyu: la memorizzazione nella cache del bytecode nei file .pyc accelera il caricamento, ma solo perché il codice Python viene compilato in bytecode prima dell'esecuzione comunque. Anche se non credo che sia stato provato specificamente con Python, altre implementazioni linguistiche mostrano che il bytecode è davvero più facile da interpretare in modo efficiente rispetto a un semplice codice AST o, peggio ancora, non analizzato. Le versioni precedenti di Ruby interpretate da AST, ad esempio, e AFAIK hanno sovraperformato un po 'le versioni più recenti che vengono compilate in bytecode.

Non vuoi sembrare scortese, ma non è quello che volevo dire (ma non così informato come te)?
Jesvin Jose,

1
@aitchnyu: non so cosa volevi dire. So solo che il tuo commento non è errato ma ha fornito una buona oppoturnity per alcune informazioni di base sul perché accelera solo il tempo di caricamento, quindi ho deciso di aggiungere tali informazioni. Nessun reato inteso o preso :)

Risposte:


232

Innanzitutto, interpretato / compilato non è una proprietà della lingua ma una proprietà dell'implementazione. Per la maggior parte delle lingue, la maggior parte se non tutte le implementazioni rientrano in una categoria, quindi è possibile salvare alcune parole dicendo che anche la lingua viene interpretata / compilata, ma è comunque una distinzione importante, sia perché aiuta la comprensione sia perché ci sono alcune lingue con implementazioni utilizzabili di entrambi i tipi (principalmente nel regno dei linguaggi funzionali, vedi Haskell e ML). Inoltre, ci sono interpreti e progetti C che tentano di compilare un sottoinsieme di codice Python in C o C ++ (e successivamente in codice macchina).

In secondo luogo, la compilazione non è limitata alla compilazione anticipata al codice macchina nativo. Un compilatore è, più in generale, un programma che converte un programma in un linguaggio di programmazione in un programma in un altro linguaggio di programmazione (probabilmente, si può anche avere un compilatore con lo stesso linguaggio di input e output se vengono applicate trasformazioni significative). E i compilatori JIT compilano il codice macchina nativo in fase di runtime , il che può dare una velocità molto vicina o addirittura migliore rispetto alla compilazione anticipata (a seconda del benchmark e della qualità delle implementazioni confrontate).

Ma per interrompere il nitpicking e rispondere alla domanda che intendevi porre: praticamente (leggi: usando un'implementazione piuttosto popolare e matura), Python è compilato . Non compilato in anticipo sul codice macchina (ovvero "compilato" dalla definizione limitata e sbagliata, ma purtroppo comune), "solo" compilato in bytecode , ma è comunque compilato con almeno alcuni dei vantaggi. Ad esempio, l'istruzione a = b.c()viene compilata in un flusso di byte che, quando "disassemblato", appare in qualche modo simile load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). Questa è una semplificazione, in realtà è meno leggibile e un po 'più di basso livello: puoi sperimentare il dismodulo libreria standard e vedere come appare il vero affare.

Tale bytecode viene interpretato (si noti che esiste una differenza, sia in teoria che in termini di prestazioni pratiche, tra l'interpretazione diretta e la prima compilazione in una rappresentazione intermedia e l'interpretazione), come con l'implementazione di riferimento (CPython), oppure sia interpretata che compilata in codice macchina ottimizzato in fase di esecuzione, come con PyPy .


2
Bene, questo significa che uno script Python viene prima compilato in bytecode e poi viene implementato da un interprete come CPython, Jython o IronPython ecc.
Pankaj Upadhyay

19
No, viene compilato in bytecode e quindi il bytecode viene eseguito dalla rispettiva VM. CPython è sia il compilatore che la VM, ma Jython e IronPython sono solo il compilatore.
Ignacio Vazquez-Abrams,

1
@Igacio: non ho molta esperienza con IronPython / Jython, ma almeno Jython non fornisce un livello da interprete? Non credo sia possibile provare a trasformare Python nel bytecode JVM tipicamente statico. Comunque, un buon punto sul fatto che compilatore ed interprete facciano parte dello stesso pacchetto.

2
+1 "... una proprietà dell'implementazione". Io stesso avrei detto "consente una shell interattiva"
Jesvin Jose

2
@delnan: Beh, Jython agisce come una sorta di intermediario tra il linguaggio Python e la VM Java, ma si compila in bytecode Java.
Ignacio Vazquez-Abrams,

34

La CPU può davvero comprendere solo il codice macchina. Per i programmi interpretati, l'obiettivo finale di un interprete è "interpretare" il codice del programma in codice macchina. Tuttavia, di solito un linguaggio interpretato moderno non interpreta direttamente il codice umano perché è troppo inefficiente.

L'interprete Python legge prima il codice umano e lo ottimizza su un codice intermedio prima di interpretarlo in codice macchina. Ecco perché hai sempre bisogno di un altro programma per eseguire uno script Python, a differenza di C ++ dove puoi eseguire direttamente l'eseguibile compilato del tuo codice. Ad esempio, c:\Python27\python.exeoppure /usr/bin/python.


11
Mi piace il punto sul "bisogno di un altro programma per eseguirlo [it]". Ciò ha contribuito a chiarire alcuni dei miei pensieri.
Matt,

quindi python.exe prima ottimizza il codice e poi lo interpreta?
Koray Tugay,

@KorayTugay, quando python.exe riceve un codice sorgente di testo leggibile dall'uomo, produce prima un codice byte ottimizzato, quindi lo interpreta (come dici tu); tuttavia, quando esiste già un file con codice byte (pre-compilato), non è necessario eseguire il primo passaggio, che consente di risparmiare tempo.
GordonBood,

31

La risposta dipende dall'implementazione di Python utilizzata. Se stai usando diciamo CPython (l'implementazione standard di python) o Jython (mirato per l'integrazione con il linguaggio di programmazione Java), viene prima tradotto in bytecode e, a seconda dell'implementazione di python che stai usando, questo bycode è diretto al corrispondente macchina virtuale per l'interpretazione . PVM (Python Virtual Machine) per CPython e JVM (Java Virtual Machine) per Jython.

Ma supponiamo che tu stia usando PyPy, che è un'altra implementazione standard di CPython. Userebbe un compilatore Just-In-Time .


Durante la traduzione in bytecode ha bisogno di un compilatore quale?
RICKY,

Pypy è un'implementazione di Python , non un'implementazione "CPython". In effetti, Pypy è un'alternativa a CPython ( pypy.org/features.html ).
Giorgio,

13

Secondo il sito ufficiale di Python è un linguaggio interpretato.

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

Python è un linguaggio di programmazione interpretato, orientato agli oggetti e di alto livello ...

...

Poiché non esiste alcun passaggio di compilazione ...

...

L'interprete Python e la vasta libreria standard sono disponibili ...

...

Invece, quando l'interprete rileva un errore, genera un'eccezione. Quando il programma non rileva l'eccezione, l'interprete stampa una traccia dello stack.


7

Sì, è un linguaggio sia compilato che interpretato. Allora perché generalmente lo chiamiamo come linguaggio interpretato?

vedi come viene compilato e interpretato?

Prima di tutto voglio dire che ti piacerà di più la mia risposta se vieni dal mondo Java.

In Java il codice sorgente viene prima convertito nel codice byte tramite il compilatore javac, quindi diretto alla JVM (responsabile della generazione del codice nativo a scopo di esecuzione). Ora voglio mostrarti che chiamiamo Java come linguaggio compilato perché possiamo vedere che compila davvero il codice sorgente e fornisce il file .class (nient'altro che bytecode) attraverso:

javac Hello.java -------> produce il file Hello.class

java Hello --------> Indirizzamento del bytecode su JVM a scopo di esecuzione

La stessa cosa accade con Python, ovvero prima il codice sorgente viene convertito nel bytecode tramite il compilatore, quindi diretto al PVM (responsabile della generazione del codice nativo a scopo di esecuzione). Ora voglio mostrarti che di solito chiamiamo Python come linguaggio interpretato perché la compilazione avviene dietro la scena e quando eseguiamo il codice Python attraverso:

python Hello.py -------> esclude direttamente il codice e possiamo vedere che l'output ha dimostrato che il codice è sintatticamente corretto

@ python Hello.py sembra che venga eseguito direttamente ma in realtà genera prima il bytecode che viene interpretato dall'interprete per produrre il codice nativo a scopo di esecuzione.

CPython : si assume la responsabilità sia della compilazione che dell'interpretazione.

Guarda nelle righe seguenti se hai bisogno di maggiori dettagli :

Come ho detto che CPython compila il codice sorgente ma la compilazione effettiva avviene con l'aiuto di cython, quindi l'interpretazione avviene con l'aiuto di CPython

Ora parliamo un po 'del ruolo del compilatore Just-In-Time in Java e Python

In JVM esiste l'interprete Java che interpreta il bytecode riga per riga per ottenere il codice macchina nativo a scopo di esecuzione ma quando il bytecode Java viene eseguito da un interprete, l'esecuzione sarà sempre più lenta. Quindi qual è la soluzione? la soluzione è il compilatore Just-In-Time che produce il codice nativo che può essere eseguito molto più rapidamente di quello che potrebbe essere interpretato. Alcuni distributori JVM usano Java Interpreter e altri usano il compilatore Just-In-Time . Riferimento: clicca qui

In python per aggirare l'interprete per ottenere l'esecuzione veloce usa un'altra implementazione di Python ( PyPy ) invece di CPython . fai clic qui per altre implementazioni di Python incluso PyPy .


6

Se (conosci Java) {il

codice Python viene convertito in bytecode come fa java.
Tale bytecode viene eseguito nuovamente ogni volta che si tenta di accedervi.

} else {Il

codice Python viene inizialmente tradotto in qualcosa chiamato bytecode
che è abbastanza vicino al linguaggio macchina ma non al codice macchina reale,
quindi ogni volta che accediamo o eseguiamo quel codice byte viene eseguito di nuovo

}


2

Quasi, possiamo dire che Python è un linguaggio interpretato. Ma stiamo usando una parte del processo di compilazione di una volta in Python per convertire il codice sorgente completo in codice byte come il linguaggio Java.


1

Per i neofiti

Python compila automaticamente lo script in codice compilato, il cosiddetto codice byte, prima di eseguirlo.

L'esecuzione di uno script non è considerata un'importazione e non verrà creato .pyc.

Ad esempio, se si dispone di un file di script abc.py che importa un altro modulo xyz.py, quando si esegue abc.py, verrà creato xyz.pyc dall'importazione di xyz, ma nessun file abc.pyc verrà creato da abc. py non viene importato.


1

È una grande confusione per le persone che hanno iniziato a lavorare su Python e le risposte qui sono un po 'difficili da comprendere, quindi renderò più facile.

Quando chiediamo a Python di eseguire il nostro script, ci sono alcuni passaggi che Python esegue prima che il nostro codice inizi effettivamente a sgretolarsi:

  • È compilato in bytecode.
  • Quindi viene instradato alla macchina virtuale.

Quando eseguiamo un codice sorgente, Python lo compila in un codice byte. La compilazione è una fase di traduzione e il codice byte è una rappresentazione di codice sorgente indipendente dalla piattaforma di basso livello. Si noti che il codice byte Python non è un codice macchina binario (ad es. Istruzioni per un chip Intel).

In realtà, Python traduce ogni istruzione del codice sorgente in istruzioni per il codice byte, scomporle in singole fasi. La traduzione del codice byte viene eseguita per velocizzare l'esecuzione. Il codice byte può essere eseguito molto più rapidamente rispetto alle istruzioni del codice sorgente originale. Ha estensione.pyc e verrà scritto se può scrivere sulla nostra macchina.

Quindi, la prossima volta che eseguiremo lo stesso programma, Python caricherà il file .pyc e salterà il passaggio della compilazione a meno che non sia stato modificato. Python controlla automaticamente i timestamp dei file di codice sorgente e byte per sapere quando deve essere ricompilato. Se ripristiniamo il codice sorgente, il codice byte viene automaticamente creato nuovamente alla successiva esecuzione del programma.

Se Python non è in grado di scrivere i file del codice byte sulla nostra macchina, il nostro programma funziona ancora. Il codice byte viene generato in memoria e semplicemente scartato all'uscita dal programma. Ma poiché i file .pyc accelerano il tempo di avvio, potremmo voler assicurarci che sia stato scritto per programmi più grandi.

Riassumiamo cosa succede dietro le quinte. Quando un Python esegue un programma, Python legge il .py in memoria e lo analizza per ottenere un bytecode, quindi continua l'esecuzione. Per ogni modulo importato dal programma, Python verifica innanzitutto se esiste una versione precompilata di bytecode, in un .pyo o .pyc, che ha un timestamp che corrisponde al suo file .py. Python utilizza l'eventuale versione bytecode. Altrimenti, analizza il file .py del modulo, lo salva in un file .pyc e utilizza il bytecode appena creato.

I file di codice byte sono anche un modo per spedire i codici Python. Python eseguirà comunque un programma se non riesce a trovare i file are.pyc, anche se i file sorgente .py originali non sono presenti.

Python Virtual Machine (PVM)

Una volta che il nostro programma è stato compilato in codice byte, viene spedito per essere eseguito su Python Virtual Machine (PVM). PVM non è un programma separato. Non è necessario che sia installato da solo. In realtà, il PVM è solo un grande ciclo che scorre attraverso le nostre istruzioni di codice byte, uno per uno, per eseguire le loro operazioni. PVM è il motore di runtime di Python. È sempre presente come parte del sistema Python. È il componente che esegue veramente i nostri script. Tecnicamente è solo l'ultimo passo di quello che viene chiamato l'interprete Python.


0

Il codice python che scrivi viene compilato in bytecode python, che crea il file con estensione .pyc. Se compila, di nuovo la domanda è, perché non compilare il linguaggio.

Nota che questa non è una compilazione nel senso tradizionale della parola. In genere, diremmo che la compilazione sta prendendo un linguaggio di alto livello e lo sta convertendo in codice macchina. Ma è una sorta di raccolta. Compilato nel codice intermedio non nel codice macchina (spero che tu l'abbia ottenuto ora).

Torna al processo di esecuzione, il tuo bytecode, presente nel file pyc, creato in fase di compilazione, viene quindi eseguito da appropriate macchine virtuali, nel nostro caso, la VM CPython Il timestamp (chiamato come numero magico) viene utilizzato per convalidare se. il file py viene modificato o meno, a seconda del nuovo file pyc creato. Se pyc è del codice corrente, salta semplicemente il passo della compilazione.


0

Python (l'interprete) è compilato .

Prova: non compilerà nemmeno il codice se contiene errori di sintassi .

Esempio 1:

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

Produzione:

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

Il codice viene compilato correttamente. La prima riga viene eseguita ( print) la seconda riga genera ZeroDivisionError(errore del tempo di esecuzione).

Esempio 2:

print("This should not print")
/0         

Produzione:

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

Conclusione : se il file di codice SyntaxErrornon contiene nulla, verrà eseguito poiché la compilazione non riesce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.