Heim > Artikel > Backend-Entwicklung > Der Ausführungsprozess eines Python-Programms umfasst die Konvertierung des Quellcodes in Bytecode (d. h. die Kompilierung) und die Ausführung des Bytecodes
Wir müssen jeden Tag einige Python-Programme schreiben, entweder um Text zu verarbeiten oder um Systemverwaltungsarbeiten durchzuführen. Nachdem das Programm geschrieben wurde, müssen Sie nur noch den Python-Befehl eingeben, um das Programm zu starten und mit der Ausführung zu beginnen:
$ python some-program.py
Wie wird also eine .py-Datei in Textform in Maschinenanweisungen umgewandelt, die von der CPU Schritt für Schritt ausgeführt werden können? Schritt? Darüber hinaus können während der Programmausführung .pyc-Dateien generiert werden. Welche Funktionen haben diese Dateien?
Obwohl Python in Bezug auf das Verhalten eher wie eine interpretierte Sprache wie Shell-Skript aussieht, ist das Ausführungsprinzip des Python-Programms im Wesentlichen das gleiche wie bei Java oder C#, was als „virtuelle Maschine“ zusammengefasst werden kann und Wörter Abschnittscode . Python führt ein Programm in zwei Schritten aus: Kompilieren Sie zunächst den Programmcode in Bytecode und starten Sie dann die virtuelle Maschine, um den Bytecode auszuführen:
Obwohl der Python-Befehl auch als Python-Interpreter bezeichnet wird, ist er im Wesentlichen mit anderen identisch Skriptspracheninterpreter machen den Unterschied. Tatsächlich besteht der Python-Interpreter aus zwei Teilen:Compiler und virtueller Maschine. Wenn der Python-Interpreter gestartet wird, führt er hauptsächlich die folgenden zwei Schritte aus:
Der Compiler kompiliert den Python-Quellcode in der .py-Datei in Bytecode. Die virtuelle Maschine führt den vom Compiler generierten Bytecode Zeile für Zeile aus. die .py-Datei Die Python-Anweisungen in werden nicht direkt in Maschinenanweisungen, sondern in Python-Bytecode umgewandelt. 2. BytecodeDas kompilierte Ergebnis des Python-Programms ist Bytecode, der viele verwandte Inhalte zur Funktionsweise von Python enthält. Unabhängig davon, ob es darum geht, den Betriebsmechanismus der virtuellen Python-Maschine besser zu verstehen oder die Betriebseffizienz des Python-Programms zu optimieren, ist der Bytecode der Schlüsselinhalt. Wie sieht also der Python-Bytecode aus? Wie können wir den Bytecode eines Python-Programms erhalten? Python bietet eine integrierte Kompilierungsfunktion für die sofortige Kompilierung des Quellcodes. Wir müssen nur die Kompilierungsfunktion mit dem zu kompilierenden Quellcode als Parameter aufrufen, um das Kompilierungsergebnis des Quellcodes zu erhalten. 3. Kompilierung des Quellcodes Nachfolgend kompilieren wir ein Programm über die Kompilierungsfunktion: Der Quellcode wird in der Datei demo.py gespeichert:PI = 3.14 def circle_area(r): return PI * r ** 2 class Person(object): def __init__(self, name): self.name = name def say(self): print('i am', self.name)Der Quellcode muss vor der Kompilierung aus der Datei gelesen werden:
>>> text = open('D:\myspace\code\pythonCode\mix\demo.py').read() >>> print(text) PI = 3.14 def circle_area(r): return PI * r ** 2 class Person(object): def __init__(self, name): self.name = name def say(self): print('i am', self.name)Dann rufen Sie auf. Die Kompilierungsfunktion kompiliert den Quellcode:
>>> result = compile(text,'D:\myspace\code\pythonCode\mix\demo.py', 'exec')Die Kompilierungsfunktion erfordert 3 Parameter: Quelle: der zu kompilierende Quellcode Dateiname: der Dateiname, in dem sich der Quellcode befindet Modus: Kompilierungsmodus, exec bedeutet, den Quellcode als Modul zu behandeln. Kompilieren Drei Kompilierungsmodi: exec: wird zum Kompilieren des Modulquellcodes verwendet. single: wird zum Kompilieren einer einzelnen Python-Anweisung verwendet (interaktiv). eval: wird zum Kompilieren verwendet ein Auswertungsausdruck 4. Durch die Kompilierungsfunktion haben wir das endgültige Ergebnis der Quellcode-Kompilierung erhalten:
>>> result <code object <module> at 0x000001DEC2FCF680, file "D:\myspace\code\pythonCode\mix\demo.py", line 1> >>> result.__class__ <class 'code'>Schließlich haben wir ein Codetypobjekt erhalten, und die entsprechende zugrunde liegende Struktur ist PyCodeObjectDer PyCodeObject-Quellcode lautet wie folgt folgt:
/* Bytecode object */ struct PyCodeObject { PyObject_HEAD int co_argcount; /* #arguments, except *args */ int co_posonlyargcount; /* #positional only arguments */ int co_kwonlyargcount; /* #keyword only arguments */ int co_nlocals; /* #local variables */ int co_stacksize; /* #entries needed for evaluation stack */ int co_flags; /* CO_..., see below */ int co_firstlineno; /* first source line number */ PyObject *co_code; /* instruction opcodes */ PyObject *co_consts; /* list (constants used) */ PyObject *co_names; /* list of strings (names used) */ PyObject *co_varnames; /* tuple of strings (local variable names) */ PyObject *co_freevars; /* tuple of strings (free variable names) */ PyObject *co_cellvars; /* tuple of strings (cell variable names) */ /* The rest aren't used in either hash or comparisons, except for co_name, used in both. This is done to preserve the name and line number for tracebacks and debuggers; otherwise, constant de-duplication would collapse identical functions/lambdas defined on different lines. */ Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See Objects/lnotab_notes.txt for details. */ void *co_zombieframe; /* for optimization only (see frameobject.c) */ PyObject *co_weakreflist; /* to support weakrefs to code objects */ /* Scratch space for extra data relating to the code object. Type is a void* to keep the format private in codeobject.c to force people to go through the proper APIs. */ void *co_extra; /* Per opcodes just-in-time cache * * To reduce cache size, we use indirect mapping from opcode index to * cache object: * cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1] */ // co_opcache_map is indexed by (next_instr - first_instr). // * 0 means there is no cache for this opcode. // * n > 0 means there is cache in co_opcache[n-1]. unsigned char *co_opcache_map; _PyOpcache *co_opcache; int co_opcache_flag; // used to determine when create a cache. unsigned char co_opcache_size; // length of co_opcache. };Das Codeobjekt PyCodeObject wird zum Speichern von Kompilierungsergebnissen verwendet, einschließlich Bytecodes und Konstanten, Namen usw., die am Code beteiligt sind. Zu den Schlüsselfeldern gehören:
Feld
co_argcount | |
---|---|
co_kwonlyargcount | Anzahl der Keyword-Parameter |
co_nlocals | Anzahl lokaler Variablen |
co_stacksize | Der zum Ausführen des Codes erforderliche Stapelplatz |
co_flags | Identification |
co_firstlineno | Die erste Zeilennummer des Codeblocks |
co_code | In Anweisung Opcode, das heißt Bytecode |
co_consts | konstante Liste |
co_names | Namensliste |
co_varnames | lokale Variablennamenliste |
Das obige ist der detaillierte Inhalt vonDer Ausführungsprozess eines Python-Programms umfasst die Konvertierung des Quellcodes in Bytecode (d. h. die Kompilierung) und die Ausführung des Bytecodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!