Frage Wenn Python interpretiert wird, was sind .pyc-Dateien?


Mir wurde klar, dass Python eine interpretierte Sprache ist ... Wenn ich mir jedoch meinen Python-Quellcode anschaue, sehe ich .pyc Dateien, die Windows als "Kompilierte Python-Dateien" identifiziert. Wo kommen diese her?


796
2018-06-08 14:27


Ursprung


Antworten:


Sie beinhalten Bytecode, woran der Python-Interpreter die Quelle kompiliert. Dieser Code wird dann von Pythons virtueller Maschine ausgeführt.

Pythons Dokumentation erklärt die Definition folgendermaßen:

Python ist eine interpretierte Sprache, als   im Gegensatz zu einer kompilierten, obwohl die   Unterscheidung kann wegen verschwommen sein   das Vorhandensein des Bytecode-Compilers.   Dies bedeutet, dass Quelldateien sein können   laufe direkt ohne explizit   Erstellen einer ausführbaren Datei, die dann ist   Lauf.


516
2018-06-08 14:28



Das habe ich verstanden   Python ist eine interpretierte Sprache ...

Dieses populäre Mem ist falsch oder eher konstruiert auf einem Missverständnis der (natürlichen) Sprachniveaus: ein ähnlicher Fehler wäre zu sagen "die Bibel ist ein Hardcover-Buch". Lass mich das Gleichnis erklären ...

"Die Bibel" ist "ein Buch" im Sinne eines Seins Klasse von (tatsächlichen, physischen Objekten identifiziert als) Bücher; die Bücher, die als "Kopien der Bibel" bezeichnet werden, sollen etwas Grundsätzliches gemeinsam haben (die Inhalte, obwohl auch diese in verschiedenen Sprachen sein können, mit verschiedenen akzeptablen Übersetzungen, Ebenen von Fußnoten und anderen Anmerkungen) - aber diese Bücher sind durchaus erlaubt, sich in einer Vielzahl von Aspekten zu unterscheiden, die sind nicht als grundlegend betrachtet - Art der Bindung, Farbe der Bindung, Schriftart (en), die beim Drucken verwendet werden, Abbildungen, falls vorhanden, breite beschreibbare Ränder oder nicht, Anzahl und Arten von eingebauten Lesezeichen usw. und so weiter.

Es ist durchaus möglich, dass a typisch Der Druck der Bibel würde in der Tat in Hardcover-Bindung sein - schließlich ist es ein Buch, das normalerweise dazu gedacht ist, immer wieder gelesen zu werden, an mehreren Stellen mit einem Lesezeichen versehen zu werden, nach bestimmten Kapitel-und-Vers-Zeigern zu suchen usw. usw Eine gute Hardcover-Bindung kann dazu führen, dass eine gegebene Kopie unter einer solchen Verwendung länger hält. Dies sind jedoch banale (praktische) Fragen, die nicht dazu verwendet werden können festzustellen, ob ein gegebenes Buchobjekt eine Kopie der Bibel ist oder nicht: Taschenbuchdrucke sind absolut möglich!

In ähnlicher Weise ist Python "eine Sprache" im Sinne der Definition einer Klasse von Sprache Implementierungen die alle in einigen grundlegenden Aspekten ähnlich sein müssen (Syntax, die meisten Semantiken mit Ausnahme derjenigen Teile, in denen sie explizit abweichen dürfen), aber es ist völlig erlaubt, sich in fast jedem "Implementierungs" -Detail zu unterscheiden - einschließlich, wie sie mit den Quelldateien, die sie erhalten, ob sie die Quellen in Formulare niedrigerer Ebene kompilieren (und wenn ja, in welches Formular - und ob sie solche kompilierten Formulare auf Diskette oder anderswo speichern), wie sie diese Formulare ausführen und so weiter .

Die klassische Implementierung, CPython, wird oft nur kurz "Python" genannt - aber es ist nur eine von mehreren Implementierungen in Produktionsqualität, Seite an Seite mit Microsoft IronPython (die zu CLR-Codes kompiliert, dh ".NET"), Jython (das kompiliert zu JVM-Codes), PyPy (das in Python selbst geschrieben wird und zu einer großen Vielfalt von "Back-End" -Formularen kompilieren kann, einschließlich "just-in-time" erzeugter Maschinensprache). Sie sind alle Python (== "Implementierungen der Python-Sprache"), genauso wie viele oberflächlich verschiedene Buchobjekte alle Bibeln (== "Kopien der Bibel") sein können.

Wenn Sie sich speziell für CPython interessieren: Er kompiliert die Quelldateien in ein Python-spezifisches Formular der unteren Ebene (bekannt als "Bytecode"), wird automatisch bei Bedarf ausgeführt (wenn es keine Bytecodedatei für eine Quelldatei gibt, oder die Bytecode-Datei ist älter als die Quelle oder von einer anderen Python-Version kompiliert), speichert die Bytecode-Dateien in der Regel auf der Festplatte (um eine Neukompilierung in der Zukunft zu vermeiden). OTOH IronPython kompiliert in der Regel zu CLR-Codes (speichert sie auf der Festplatte oder nicht, abhängig) und Jython zu JVM-Codes (speichert sie auf der Festplatte oder nicht - es wird die verwenden .class Erweiterung, wenn es sie speichert).

Diese Formulare auf niedrigerer Ebene werden dann von geeigneten "virtuellen Maschinen" ausgeführt, die auch als "Interpreter" bezeichnet werden - der CPython-VM, der .Net-Laufzeitumgebung, der Java-VM (auch als JVM bezeichnet).

In diesem Sinne (was typische Implementierungen tun) ist Python genau dann eine "interpretierte Sprache", wenn C # und Java sind: Alle haben eine typische Implementierungsstrategie, Bytecode zuerst zu erzeugen und dann über einen VM / Interpreter auszuführen .

Wahrscheinlicher ist der Fokus darauf, wie "schwer", langsam und hochzeremoniell der Kompilierungsprozess ist. CPython wurde entwickelt, um so schnell wie möglich, so leicht wie möglich, mit so wenig Zeremonien wie möglich zu kompilieren - der Compiler führt sehr wenig Fehlerprüfung und -optimierung durch, so dass er schnell und in kleinen Mengen von Arbeitsspeicher ausgeführt werden kann automatisch und transparent ausgeführt werden, wann immer dies erforderlich ist, ohne dass der Benutzer sich bewusst sein muss, dass die meiste Zeit eine Kompilierung stattfindet. Java und C # akzeptieren normalerweise mehr Arbeit während der Kompilierung (und führen daher keine automatische Kompilierung durch), um Fehler genauer zu prüfen und mehr Optimierungen durchzuführen. Es ist ein Kontinuum von Graustufen, keine Schwarz- oder Weiß-Situation, und es wäre äußerst willkürlich, einen Schwellenwert auf eine bestimmte Ebene zu setzen und zu sagen, dass man nur über dieser Ebene "Compilation" nennt!


779
2018-06-08 15:00



Es gibt keine interpretierte Sprache. Ob ein Interpreter oder ein Compiler verwendet wird, ist eine Eigenschaft des Implementierung und hat absolut nichts mit der Sprache zu tun.

Jeden Sprache kann entweder durch einen Interpreter oder einen Compiler implementiert werden. Die große Mehrheit der Sprachen hat mindestens eine Implementierung für jeden Typ. (Zum Beispiel gibt es Interpreter für C und C ++ und es gibt Compiler für JavaScript, PHP, Perl, Python und Ruby.) Außerdem kombiniert die Mehrheit der modernen Sprachimplementierungen tatsächlich sowohl einen Interpreter als auch einen Compiler (oder sogar mehrere Compiler).

Eine Sprache ist nur ein Satz abstrakter mathematischer Regeln. Ein Interpreter ist eine von mehreren konkreten Implementierungsstrategien für eine Sprache. Diese beiden leben auf völlig unterschiedlichen Abstraktionsebenen. Wenn Englisch eine getippte Sprache wäre, wäre der Begriff "interpretierte Sprache" ein Typfehler. Die Aussage "Python ist eine interpretierte Sprache" ist nicht nur falsch (weil falsch zu sein bedeutet, dass die Aussage sogar Sinn macht, auch wenn sie falsch ist), macht sie einfach nicht Sinn, weil eine Sprache kann noch nie als "interpretiert" definiert werden.

Insbesondere wenn Sie sich die aktuell vorhandenen Python-Implementierungen ansehen, sind dies die Implementierungsstrategien, die sie verwenden:

  • IronPython: kompiliert zu DLR-Bäumen, die der DLR dann zu CIL-Bytecode kompiliert. Was mit dem CIL-Bytecode geschieht, hängt davon ab, auf welchem ​​CLI-VES Sie laufen, aber Microsoft .NET, GNU Portable.NET und Novell Mono werden es schließlich zu nativem Maschinencode kompilieren.
  • Jython: Interpretiert den Python-Quellcode, bis er die Hot-Code-Pfade identifiziert, die er dann zu JVML-Bytecode kompiliert. Was mit dem JVML-Bytecode passiert, hängt davon ab, auf welcher JVM Sie laufen. Maxine kompiliert es direkt zu nicht optimiertem nativem Code, bis es die Hot-Code-Pfade identifiziert, die dann zu optimiertem nativem Code kompiliert werden. HotSpot interpretiert zuerst den JVML-Bytecode und kompiliert schließlich die Hot-Code-Pfade zu optimiertem Maschinencode.
  • PyPy: Kompiliert zu PyPy Bytecode, der dann von der PyPy VM interpretiert wird, bis er die Hot-Code-Pfade identifiziert, die er dann in nativen Code, JVML-Bytecode oder CIL-Bytecode kompiliert, abhängig davon, auf welcher Plattform Sie gerade laufen.
  • CPython: kompiliert zu CPython-Bytecode, den er dann interpretiert.
  • Stackless Python: Kompiliert zu CPython-Bytecode, den er dann interpretiert.
  • Unload Swallow: kompiliert zu CPython-Bytecode, den er interpretiert, bis er die Hot-Code-Pfade identifiziert, die er dann zu LLVM IR kompiliert, die der LLVM-Compiler dann zu nativem Maschinencode kompiliert.

Sie werden vielleicht bemerken, dass jede einzelne der Implementierungen in dieser Liste (plus einige andere, die ich nicht erwähnt habe, wie Tinypy, Shedskin oder Psyco) einen Compiler hat. Soweit ich weiß, gibt es derzeit keine Python-Implementierung, die rein interpretiert wird, eine solche Implementierung ist nicht geplant und es gab noch nie eine solche Implementierung.

Der Begriff "interpretierte Sprache" macht nicht nur keinen Sinn, auch wenn Sie ihn als "Sprache mit interpretierter Umsetzung" interpretieren, ist er eindeutig nicht wahr. Wer dir das erzählt hat, weiß offensichtlich nicht wovon er redet.

Insbesondere die .pyc Dateien, die Sie sehen, sind zwischengespeicherte Bytecode-Dateien, die von CPython, Stackless Python oder Unladen Swallow erstellt wurden.


126
2018-06-08 15:25



Diese werden vom Python-Interpreter erstellt, wenn a .py Datei wird importiert, und sie enthalten den "kompilierten Bytecode" des importierten Moduls / Programms, wobei die Idee darin besteht, dass die "Übersetzung" von Quellcode in Bytecode (die nur einmal durchgeführt werden muss) später übersprungen werden kann imports wenn die .pyc ist neuer als das entsprechende .py Datei, wodurch der Startvorgang etwas beschleunigt wird. Aber es wird immer noch interpretiert.


55
2018-06-08 14:30



Python (zumindest die gebräuchlichste Implementierung davon) folgt einem Muster, bei dem die ursprünglichen Quellcode-Byte-Codes kompiliert werden und dann die Byte-Codes auf einer virtuellen Maschine interpretiert werden. Dies bedeutet, dass (wiederum die gängigste Implementierung) weder ein reiner Interpreter noch ein reiner Compiler ist.

Die andere Seite ist jedoch, dass der Kompilierungsprozess größtenteils verborgen ist - die .pyc-Dateien werden grundsätzlich wie ein Cache behandelt; Sie beschleunigen die Dinge, aber normalerweise müssen Sie sich ihrer gar nicht bewusst sein. Es wird automatisch ungültig und lädt sie erneut (es kompiliert den Quellcode erneut), wenn dies aufgrund von Dateizeit- / Datumsstempeln erforderlich ist.

Etwa das einzige Mal, dass ich ein Problem damit hatte, war, dass eine kompilierte Bytecode-Datei irgendwie einen Zeitstempel in die Zukunft bekam, was bedeutete, dass sie immer neuer aussah als die Quelldatei. Da es neuer aussah, wurde die Quelldatei nie neu kompiliert, egal welche Änderungen Sie vorgenommen haben, sie wurden ignoriert ...


20
2018-06-08 15:01



DAS IST FÜR ANFÄNGER,

Python kompiliert Ihr Skript automatisch zu kompiliertem Code, dem sogenannten Byte-Code, bevor es ausgeführt wird.

Das Ausführen eines Skripts gilt nicht als Import, und es wird keine .pyc-Datei erstellt.

Zum Beispiel, wenn Sie eine Skriptdatei haben abc.py Das importiert ein anderes Modul xyz.pywenn du rennst abc.py, xyz.pyc wird erstellt, da xyz importiert wird, aber keine abc.pyc-Datei wird erstellt da abc.py nicht importiert wird.

Wenn Sie eine .pyc-Datei für ein Modul erstellen müssen, das nicht importiert wird, können Sie die .pyc-Datei verwenden py_compile und compileall Module.

Das py_compile Modul kann jedes Modul manuell kompilieren. Eine Möglichkeit ist die Verwendung der py_compile.compile Funktion in diesem Modul interaktiv:

>>> import py_compile
>>> py_compile.compile('abc.py')

Dadurch wird die .pyc an denselben Speicherort wie abc.py geschrieben (Sie können dies mit dem optionalen Parameter überschreiben cfile).

Sie können auch automatisch alle Dateien in einem Verzeichnis oder in Verzeichnissen mit dem Compile-Modul kompilieren.

python -m compileall

Wenn der Verzeichnisname (das aktuelle Verzeichnis in diesem Beispiel) weggelassen wird, kompiliert das Modul alles, was gefunden wurde sys.path


18
2017-11-03 06:47



Um das Laden von Modulen zu beschleunigen, speichert Python den kompilierten Inhalt von Modulen in .pyc.

CPython kompiliert seinen Quellcode in "Bytecode" und speichert diesen Bytecode aus Performance-Gründen im Dateisystem zwischen, wenn die Quelldatei Änderungen aufweist. Dies macht das Laden von Python-Modulen viel schneller, da die Kompilierungsphase umgangen werden kann. Wenn Ihre Quelldatei foo.py ist, speichert CPython den Byte-Code in einer foo.pyc-Datei direkt neben der Quelle.

In Python3 ist Pythons Importmaschinerie erweitert worden, um Bytecodecache-Dateien in einem einzigen Verzeichnis innerhalb jedes Python-Paketverzeichnisses zu schreiben und zu suchen. Dieses Verzeichnis wird __pycache__ heißen.

Hier ist ein Flussdiagramm, das beschreibt, wie Module geladen werden:

enter image description here

Für mehr Informationen:

Ref:PEP3147
Ref:"Kompilierte" Python-Dateien


16
2017-07-11 17:04



Pythons * .py-Datei ist nur eine Textdatei, in die Sie einige Zeilen Code schreiben. Wenn Sie versuchen, diese Datei mit "python filename.py" auszuführen,

Dieser Befehl ruft Python Virtual Machine auf. Python Virtual Machine hat 2 Komponenten: "Compiler" und "Interpreter". Der Interpreter kann den Text in der * .py-Datei nicht direkt lesen, daher wird dieser Text zuerst in einen Byte-Code konvertiert, der auf den PVM ausgerichtet ist (keine Hardware, sondern PVM). PVM führt diesen Bytecode aus. * .pyc Datei wird auch generiert, als Teil der Ausführung, die den Importvorgang für eine Datei in der Shell oder in einer anderen Datei ausführt.

Wenn diese * .pyc-Datei bereits generiert wird, lädt das System bei jedem nächsten Start / Ausführen Ihrer * .py-Datei direkt Ihre * .pyc-Datei, die keine Kompilierung benötigt (Dadurch sparen Sie einige Maschinenzyklen des Prozessors).

Sobald die * .pyc-Datei generiert wurde, ist keine * .py-Datei erforderlich, es sei denn, Sie bearbeiten sie.


9
2017-12-15 06:03



Python-Code durchläuft 2 Phasen. Der erste Schritt kompiliert den Code in .pyc-Dateien, was eigentlich ein Bytecode ist. Dann wird diese .pyc-Datei (Bytecode) mit dem CPython-Interpreter interpretiert. Bitte beziehen Sie sich auf Dies Verknüpfung. Hier wird der Vorgang der Code-Kompilierung und -Ausführung in einfachen Worten erklärt.


7
2018-03-26 06:41