Perché Python ha bisogno sia di un compilatore che di un interprete?


9

Posso capire il fatto che Java ha bisogno sia di un compilatore che di un interprete. Compila il codice sorgente in bytecode e quindi una macchina virtuale (su Windows, su Linux, su Android, ecc.) Traduce quel bytecode in codice macchina per l'architettura corrente.

Ma perché Python ha bisogno sia di un compilatore che di un interprete? Poiché Python non è indipendente dalla piattaforma, perché non usare semplicemente l'interpretazione? Per quanto ne so, non è possibile eseguire un programma Python (compilato in bytecode) su qualsiasi macchina Windows o Linux senza modifiche. O mi sbaglio?


Potresti sbagliarti. Se usi Lua invece di Python, sbaglieresti.
Basile Starynkevitch l'

Risposte:


13

Per quanto ne so, non è possibile eseguire un programma Python (compilato in bytecode) su ogni macchina, come su Windows o su Linux senza modifiche.

Sei errato Il bytecode python è multipiattaforma. Vedi Bytecode python dipende dalla versione? Dipende dalla piattaforma? su Stack Overflow. Tuttavia, non è compatibile tra le versioni. Python 2.6 non può eseguire file Python 2.5. Quindi, sebbene multipiattaforma, non è generalmente utile come formato di distribuzione.

Ma perché Python ha bisogno sia di un compilatore che di un interprete?

Velocità. L'interpretazione rigorosa è lenta. Praticamente ogni linguaggio "interpretato" in realtà compila il codice sorgente in una sorta di rappresentazione interna in modo che non debba analizzare ripetutamente il codice. Nel caso di Python salva questa rappresentazione interna su disco in modo da poter saltare il processo di analisi / compilazione la prossima volta che ha bisogno del codice.


7

Posso capire il fatto che Java ha bisogno sia di un compilatore che di un interprete.

Non Non c'è nulla nella specifica del linguaggio Java che dice che Java deve avere un compilatore. Inoltre, nelle specifiche del linguaggio Java non c'è nulla che affermi che Java deve avere un interprete.

Se utilizzare un interprete, un compilatore o una combinazione dei due, è completamente a discrezione dell'implementatore.

In realtà, ci sono implementazioni di Java che possono essere compilati direttamente in codice macchina, ad esempio il compilatore GNU per Java gcj. Tecnicamente parlando, il compilatore Java Oracle OpenJDK compila anche il codice macchina, in particolare il codice byte JVM. Ora, potresti dire, aspetta un minuto, non è un codice macchina! Ma ci sono interpreti software per il codice macchina x86 e ci sono CPU hardware che possono eseguire il codice byte JVM, quindi cosa rende uno "nativo" e l'altro no?

Si noti che il codice byte JVM si trova al di fuori delle specifiche del linguaggio Java, proprio come fa il codice macchina x86.

e quindi una macchina virtuale (su Windows, su Linux, su Android, ecc.) traduce quel bytecode in codice macchina per l'architettura corrente.

Ancora una volta, ciò dipende esclusivamente dall'implementatore.

L'originale Sun JVM non ha mai tradotto, ha sempre interpretato. L'attuale Oracle OpenJDK JVM interpreta e vengono compilate solo quelle parti che vengono eseguite spesso. La VM di ricerca Maxine viene sempre compilata da JIT. L'implementazione di Excelsior.JET viene compilata una volta, in anticipo. La JVM IKVM.NET si compila in codice byte CIL. Android Runtime viene compilato in anticipo, una volta, durante l'installazione. (Inoltre, Android Runtime non comprende il codice byte JVM, utilizza il codice byte Dalvik, che è una lingua completamente diversa.)

Ma perché Python ha bisogno sia di un compilatore che di un interprete?

Ancora una volta, non lo fa. Nulla nella specifica del linguaggio Python afferma che Python deve avere un compilatore. Non c'è inoltre nulla nella specifica del linguaggio Python che affermi che Python deve avere un interprete.

Si noti che in realtà Python non viene mai interpretato. Tutte le implementazioni Python esistenti compilano sempre Python in una lingua diversa. Quella lingua può o meno essere interpretata, a sua volta, ma quella lingua è una lingua diversa da Python. Python non viene interpretato.

perché non usare solo l'interpretazione?

Perché Python non è progettato per essere facilmente interpretato dalle macchine. È progettato per essere facilmente interpretato dall'uomo. OTOH, codice byte CPython, è progettato per essere facilmente interpretato dalle macchine. Quindi, ha senso scrivere il codice in una lingua progettata per gli umani e interpretare in una lingua progettata per le macchine, e per passare l'una dall'altra è necessario compilare.

Per quanto ne so, non è possibile eseguire un programma Python (compilato in bytecode) su qualsiasi macchina Windows o Linux senza modifiche.

Si, puoi. La VM CPython è disponibile sia per Windows che per Linux, così come PyPy, Jython e IronPython.


Le lingue non devono essere compilate o interpretate. Le lingue lo sono . In effetti, una lingua può esistere perfettamente senza alcun interprete o compilatore! Ad esempio, Plankalkül di Konrad Zuse, che ha progettato negli anni '30, non è mai stato implementato durante la sua vita. Potresti ancora scrivere dei programmi in esso, puoi analizzare quei programmi, ragionare su di essi, dimostrare le proprietà su di essi ... semplicemente non puoi eseguirli. (Beh, in realtà, anche quello è sbagliato: puoi ovviamente eseguirli nella tua testa o con carta e penna.)

Ora, qualsiasi implementazione particolare di una lingua può usare un compilatore (o anche più compilatori), un interprete o qualsiasi combinazione. Ma questo è un tratto dell'implementazione , non del linguaggio. Ogni lingua può essere implementata con un compilatore e ogni lingua può essere implementata con un interprete.

Si noti, tuttavia, che non è possibile eseguire un programma senza un interprete. Un compilatore traduce semplicemente un programma da una lingua all'altra. Ma questo è tutto. Ora hai lo stesso programma, solo in una lingua diversa. L' unico modo per ottenere effettivamente un risultato del programma è interpretarlo . A volte, il linguaggio è un linguaggio binario estremamente semplice e l'interprete è effettivamente codificato in silicone (e lo chiamiamo "CPU"), ma è comunque interpretazione.

Potresti anche essere interessato a questa mia risposta, che spiega le differenze e i diversi modi di combinare interpreti, compilatori JIT e compilatori AOT e questa risposta che tratta delle differenze tra un compilatore AOT e un compilatore JIT .


3
Le risposte che trascorrono la maggior parte del loro tempo a essere pedanti invece di rispondere alla domanda mi rendono triste.
Winston Ewert,

3

È vero che il bytecode non è adatto come formato di distribuzione, ma ciò non significa che sia inutile. Oltre a migliorare i tempi di avvio su una determinata macchina, dopo la prima esecuzione, l'interpretazione del bytecode è anche molto più semplice dell'interpretazione di un AST o, per di più, l'interpretazione riga per riga.

Bytecode è una rappresentazione del codice più a basso livello, più regolare, più compatta (sia semanticamente che in termini di layout di memoria). L'ordine delle operazioni è già definito, i nomi delle variabili locali sono stati risolti in una forma più semplice (indici interi). Nessuna sintassi complicata da seguire, solo una semplice istruzione dopo l'altra. Inoltre, è necessario meno stato: per l'interpretazione riga per riga, in pratica è necessario mantenere un intero parser in giro, e un interprete AST fa esplodere lo stack di chiamate con il suo attraversamento dell'albero, mentre un interprete bytecode ha solo bisogno di un piccolo stack per valori temporanei e gente del posto.

Questi e altri fattori cospirano per rendere gli interpreti bytecode significativamente più veloci di altri interpreti.

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.