Mi è stato dato di capire che Python è un linguaggio interpretato ...
Tuttavia, quando guardo il mio codice sorgente Python vedo i .pyc
file, che Windows identifica come "File Python compilati".
Da dove vengono questi?
java
e javac
.
Mi è stato dato di capire che Python è un linguaggio interpretato ...
Tuttavia, quando guardo il mio codice sorgente Python vedo i .pyc
file, che Windows identifica come "File Python compilati".
Da dove vengono questi?
java
e javac
.
Risposte:
Contengono il codice byte , che è quello in cui l'interprete Python compila l'origine. Questo codice viene quindi eseguito dalla macchina virtuale di Python.
La documentazione di Python spiega la definizione in questo modo:
Python è un linguaggio interpretato, al contrario di un linguaggio compilato, sebbene la distinzione possa essere sfocata a causa della presenza del compilatore bytecode. Ciò significa che i file di origine possono essere eseguiti direttamente senza creare esplicitamente un eseguibile che viene quindi eseguito.
Mi è stato dato di capire che Python è un linguaggio interpretato ...
Questo meme popolare non è corretto, o, piuttosto, costruito su un fraintendimento dei livelli linguistici (naturali): un errore simile sarebbe quello di dire "la Bibbia è un libro con copertina rigida". Lasciami spiegare quella similitudine ...
"La Bibbia" è "un libro" nel senso di essere una classe di (oggetti reali, fisici identificati come) libri; i libri identificati come "copie della Bibbia" dovrebbero avere qualcosa di fondamentale in comune (i contenuti, sebbene anche quelli possano essere in lingue diverse, con diverse traduzioni accettabili, livelli di note a piè di pagina e altre annotazioni) - tuttavia, quei libri sono perfettamente permesso di differenziarsi in una miriade di aspetti che non sono considerati fondamentali: tipo di rilegatura, colore della rilegatura, carattere (i) usato (i) nella stampa, eventuali illustrazioni, ampi margini scrivibili o meno, numeri e tipi di segnalibri incorporati , E così via e così via.
È del tutto possibile che una tipica stampa della Bibbia sia effettivamente rilegata in copertina rigida - dopotutto, è un libro che in genere deve essere letto e rilegato, aggiunto ai segnalibri in diversi punti, sfogliato cercando puntatori di capitoli e versetti , ecc., ecc. e una buona rilegatura con copertina rigida può prolungare la durata di una determinata copia con tale uso. Tuttavia, si tratta di questioni banali (pratiche) che non possono essere utilizzate per determinare se un determinato oggetto libro reale è una copia della Bibbia o no: le stampe tascabili sono perfettamente possibili!
Allo stesso modo, Python è "un linguaggio" nel senso di definire una classe di implementazioni linguistiche che devono essere tutte simili per alcuni aspetti fondamentali (sintassi, la maggior parte della semantica tranne quelle parti di quelle in cui sono esplicitamente autorizzati a differire) ma sono pienamente autorizzati differire in quasi ogni dettaglio di "implementazione", incluso il modo in cui gestiscono i file di origine che vengono forniti, se compilano i sorgenti in alcuni moduli di livello inferiore (e, in tal caso, quale modulo) e se salvano tali moduli compilati, su disco o altrove), come eseguono tali moduli e così via.
L'implementazione classica, CPython, è spesso chiamata semplicemente "Python" in breve - ma è solo una delle numerose implementazioni di qualità di produzione, affiancate da IronPython di Microsoft (che si compila in codici CLR, ovvero ".NET"), Jython (che compila i codici JVM), PyPy (che è scritto nello stesso Python e può essere compilato in una grande varietà di forme "back-end" incluso il linguaggio macchina generato "just-in-time"). Sono tutti Python (== "implementazioni del linguaggio Python") proprio come molti oggetti di libri superficialmente diversi possono essere tutti Bibbie (== "copie della Bibbia").
Se sei interessato a CPython in particolare: compila i file sorgente in un modulo di livello inferiore specifico di Python (noto come "bytecode"), lo fa automaticamente quando necessario (quando non esiste un file bytecode corrispondente a un file sorgente, oppure il file bytecode è più vecchio del sorgente o compilato da una diversa versione di Python), di solito salva i file bytecode su disco (per evitare di ricompilarli in futuro). OTOH IronPython generalmente si compila in codici CLR (salvandoli su disco o meno, a seconda) e Jython in codici JVM (salvandoli su disco o meno - utilizzerà l' .class
estensione se li salva).
Questi moduli di livello inferiore vengono quindi eseguiti da "macchine virtuali" appropriate anche note come "interpreti": la VM CPython, il runtime .Net, la VM Java (aka JVM), a seconda dei casi.
Quindi, in questo senso (cosa fanno le implementazioni tipiche), Python è un "linguaggio interpretato" se e solo se C # e Java lo sono: tutti hanno una tipica strategia di implementazione per produrre prima il bytecode, quindi eseguirlo tramite un VM / interprete .
Più probabilmente l'attenzione si concentra su quanto "pesante", lento e cerimonia sia il processo di compilazione. CPython è progettato per compilare il più velocemente possibile, il più leggero possibile, con il minor numero di cerimonie possibile: il compilatore esegue pochissimi controlli e ottimizzazioni degli errori, quindi può funzionare velocemente e con piccole quantità di memoria, che a sua volta gli consente essere eseguito automaticamente e in modo trasparente ogni volta che è necessario, senza che l'utente debba nemmeno essere consapevole che c'è una compilazione in corso, il più delle volte. Java e C # in genere accettano più lavoro durante la compilazione (e quindi non eseguono la compilazione automatica) al fine di controllare gli errori in modo più approfondito ed eseguire ulteriori ottimizzazioni. È un continuum di squame grigie, non una situazione in bianco o nero,
Non esiste un linguaggio interpretato. L'utilizzo di un interprete o di un compilatore è puramente una caratteristica dell'implementazione e non ha assolutamente nulla a che fare con il linguaggio.
Ogni lingua può essere implementata da un interprete o da un compilatore. La stragrande maggioranza delle lingue ha almeno un'implementazione di ciascun tipo. (Ad esempio, ci sono interpreti per C e C ++ e ci sono compilatori per JavaScript, PHP, Perl, Python e Ruby.) Inoltre, la maggior parte delle implementazioni linguistiche moderne in realtà combina sia un interprete che un compilatore (o anche più compilatori).
Una lingua è solo un insieme di regole matematiche astratte. Un interprete è una delle diverse strategie di implementazione concrete per una lingua. Quei due vivono su livelli di astrazione completamente diversi. Se l'inglese fosse una lingua tipizzata, il termine "lingua interpretata" sarebbe un errore di tipo. L'affermazione "Python è un linguaggio interpretato" non è solo falsa (perché essere falsi implicherebbe che l'affermazione ha persino senso, anche se è sbagliata), semplicemente non ha senso , perché un linguaggio non può mai essere definito come "interpretato."
In particolare, se guardi alle implementazioni Python attualmente esistenti, queste sono le strategie di implementazione che stanno usando:
Potresti notare che ognuna delle implementazioni in quella lista (più alcune altre che non ho menzionato, come tinypy, Shedskin o Psyco) ha un compilatore. In effetti, per quanto ne so, al momento non esiste un'implementazione di Python che sia puramente interpretata, non esiste una tale implementazione pianificata e non c'è mai stata una tale implementazione.
Non solo il termine "linguaggio interpretato" non ha senso, anche se lo interpretate come "linguaggio con implementazione interpretata", non è chiaramente vero. Chiunque te lo abbia detto, ovviamente non sa di cosa sta parlando.
In particolare, i .pyc
file visualizzati sono file di bytecode memorizzati nella cache prodotti da CPython, Stackless Python o Unladen Swallow.
Questi vengono creati dall'interprete Python quando un .py
file viene importato e contengono il "bytecode compilato" del modulo / programma importato, con l'idea che la "traduzione" dal codice sorgente al bytecode (che deve essere eseguita una sola volta) può essere saltato sui messaggi successivi import
se .pyc
è più recente del .py
file corrispondente , accelerando così un po 'l'avvio. Ma è ancora interpretato.
Per accelerare il caricamento dei moduli, Python memorizza nella cache il contenuto compilato dei moduli in .pyc.
CPython compila il suo codice sorgente in "codice byte" e, per motivi di prestazioni, memorizza nella cache questo codice byte sul file system ogni volta che il file sorgente viene modificato. Questo rende il caricamento dei moduli Python molto più veloce perché la fase di compilazione può essere bypassata. Quando il file sorgente è foo.py, CPython memorizza nella cache il codice byte in un file foo.pyc proprio accanto alla fonte.
In python3, le macchine di importazione di Python sono estese per scrivere e cercare file cache di codice byte in una singola directory all'interno di ogni directory del pacchetto Python. Questa directory si chiamerà __pycache__.
Ecco un diagramma di flusso che descrive come vengono caricati i moduli:
Per maggiori informazioni:
ref: PEP3147
ref: file Python “compilati”
Questo è per i principianti,
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.
Se è necessario creare un file .pyc per un modulo non importato, è possibile utilizzare i moduli py_compile
e compileall
.
Il py_compile
modulo può compilare manualmente qualsiasi modulo. Un modo è utilizzare la py_compile.compile
funzione in quel modulo in modo interattivo:
>>> import py_compile
>>> py_compile.compile('abc.py')
Questo scriverà il .pyc nella stessa posizione di abc.py (puoi sovrascriverlo con il parametro opzionale cfile
).
Puoi anche compilare automaticamente tutti i file in una directory o directory usando il modulo compileall.
python -m compileall
Se il nome della directory (la directory corrente in questo esempio) viene omesso, il modulo compila tutto ciò che si trova su sys.path
Python (almeno l'implementazione più comune di esso) segue uno schema di compilazione del codice sorgente originale in codici byte, quindi di interpretazione dei codici byte su una macchina virtuale. Questo significa (di nuovo, l'implementazione più comune) non è né un interprete puro né un compilatore puro.
L'altro lato di questo è, tuttavia, che il processo di compilazione è per lo più nascosto: i file .pyc sono sostanzialmente trattati come una cache; accelerano le cose, ma normalmente non devi esserne affatto consapevole. Invalida automaticamente e li carica nuovamente (ricompila nuovamente il codice sorgente) quando necessario in base ai timestamp di data / ora del file.
Circa l'unica volta che ho visto un problema con questo è stato quando un file bytecode compilato in qualche modo ha avuto un timestamp nel futuro, il che significava che sembrava sempre più nuovo del file di origine. Dal momento che sembrava più recente, il file di origine non è mai stato ricompilato, quindi indipendentemente dalle modifiche apportate, sono state ignorate ...
Il file * .py di Python è solo un file di testo in cui scrivi alcune righe di codice. Quando si tenta di eseguire questo file usando dire "python nomefile.py"
Questo comando richiama Python Virtual Machine. Python Virtual Machine ha 2 componenti: "compilatore" e "interprete". L'interprete non può leggere direttamente il testo nel file * .py, quindi questo testo viene prima convertito in un codice byte che è indirizzato al PVM (non hardware ma PVM) . PVM esegue questo codice byte. Viene anche generato il file * .pyc, come parte dell'esecuzione che esegue l'operazione di importazione su file nella shell o in qualche altro file.
Se questo file * .pyc è già generato, ogni volta che esegui / esegui il tuo file * .py, il sistema carica direttamente il tuo file * .pyc che non necessita di alcuna compilazione (questo ti farà risparmiare alcuni cicli macchina del processore).
Una volta generato il file * .pyc, non è necessario il file * .py, a meno che non venga modificato.
Il codice Python passa attraverso 2 fasi. Il primo passo compila il codice in file .pyc che in realtà è un bytecode. Quindi questo file .pyc (bytecode) viene interpretato usando l'interprete CPython. Si prega di fare riferimento a questo link. Qui il processo di compilazione ed esecuzione del codice è spiegato in termini semplici.