


Welche Rolle spielt das Codeobjekt in der virtuellen Python-Maschine?
Codeobjekt-Datenstruktur
typedef struct { PyObject_HEAD int co_argcount; /* #arguments, except *args */ 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 */ 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) and co_firstlineno (used only in comparisons). 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. */ unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ int co_firstlineno; /* first source line number */ PyObject *co_lnotab; /* 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 */ } PyCodeObject;
Das Folgende ist die Rolle jedes Felds im Codeobjekt:
Zunächst müssen Sie das Konzept des Codeblocks verstehen , das als kleine Einheit als Ganzes ausgeführt wird. Zu den gängigen Codeblöcken in Python gehören: Funktionskörper, Klassendefinition und ein Modul.
argcount, dies stellt die Anzahl der Parameter in einem Codeblock dar. Dieser Parameter ist nur für Funktionskörpercodeblöcke nützlich, da die obige Funktion pycdemo.py beispielsweise ein Modul und keine Funktion sein kann , also dieser Parameter Der entsprechende Wert ist 0.
co_code, der spezifische Inhalt dieses Objekts ist eine Bytesequenz, die echten Python-Bytecode speichert. Er wird hauptsächlich für die Ausführung virtueller Python-Maschinen verwendet und wird in diesem Artikel nicht im Detail analysiert.
co_consts, dieses Feld ist ein Listenfeld, das hauptsächlich einige Zeichenfolgenkonstanten und numerische Konstanten enthält, z. B. „__main__“ und 100 oben.
co_filename, die Bedeutung dieses Feldes ist der Dateiname der entsprechenden Quelldatei.
co_firstlineno, die Bedeutung dieses Feldes ist die Anzahl der Zeilen, die in der ersten Codezeile in der Python-Quelldatei erscheinen. Dieses Feld ist beim Debuggen sehr wichtig.
co_flags, die Hauptbedeutung dieses Feldes besteht darin, den Typ dieses Codeobjekts zu identifizieren. 0x0080 zeigt an, dass es sich bei diesem Block um eine Coroutine handelt, 0x0010 zeigt an, dass dieses Codeobjekt verschachtelt ist und so weiter.
co_lnotab, die Bedeutung dieses Feldes wird hauptsächlich zur Berechnung der Anzahl der Quellcodezeilen verwendet, die jeder Bytecode-Anweisung entsprechen.
co_varnames, die Hauptbedeutung dieses Feldes besteht darin, einen Namen darzustellen, der lokal in einem Codeobjekt definiert ist.
co_names, das Gegenteil von co_varnames, stellt Namen dar, die nicht lokal definiert, sondern im Codeobjekt verwendet werden.
co_nlocals, dieses Feld gibt die Anzahl der lokal in einem Codeobjekt verwendeten Variablen an.
co_stackszie, da die virtuelle Python-Maschine ein Stapelcomputer ist, gibt der Wert dieses Parameters den für diesen Stapel erforderlichen Maximalwert an.
co_cellvars, co_freevars, diese beiden Felder beziehen sich hauptsächlich auf verschachtelte Funktionen und Funktionsabschlüsse. Wir werden dieses Feld in den folgenden Artikeln ausführlich erläutern.
Detaillierte Analyse von Codeobjekten
Jetzt verwenden wir einige praktische Beispiele, um bestimmte Codeobjekte zu analysieren.
import dis import binascii import types d = 10 def test_co01(c): a = 1 b = 2 return a + b + c + d
Im vorherigen Artikel haben wir erwähnt, dass eine Funktion ein Codeobjektobjekt enthält. Das Ausgabeergebnis des Codeobjektobjekts von test_co01 (siehe co01 für den vollständigen Code) lautet wie folgt:
code argcount 1 nlocals 3 stacksize 2 flags 0043 0x43 code b'6401007d01006402007d02007c01007c0200177c0000177400001753' 9 0 LOAD_CONST 1 (1) 3 STORE_FAST 1 (a) 10 6 LOAD_CONST 2 (2) 9 STORE_FAST 2 (b) 11 12 LOAD_FAST 1 (a) 15 LOAD_FAST 2 (b) 18 BINARY_ADD 19 LOAD_FAST 0 (c) 22 BINARY_ADD 23 LOAD_GLOBAL 0 (d) 26 BINARY_ADD 27 RETURN_VALUE consts None 1 2 names ('d',) varnames ('c', 'a', 'b') freevars () cellvars () filename '/tmp/pycharm_project_396/co01.py' name 'test_co01' firstlineno 8 lnotab b'000106010601'
Der Wert des Feldes argcount ist gleich 1, was darauf hinweist, dass die Funktion einen Parameter hat und dass diese Funktion test_co01 einen Parameter c hat, der einander entspricht.
Der Wert des Felds nlocals ist gleich 3, was darauf hinweist, dass in der Funktion test_co01 insgesamt drei lokale Funktionsvariablen a, b, c implementiert sind.
Die Feldnamen entsprechen co_names im Code. Gemäß der vorherigen Definition wird die globale Variable d in der Funktion test_co01 verwendet, sie ist jedoch nicht in der Funktion definiert.
Feldvariablennamen, dies stellt die in lokalen Definitionen verwendeten Variablen dar. In der Funktion test_co01 gibt es drei Hauptvariablen a, b, c.
Das Feld Dateiname ist die Adresse der Python-Datei.
Field firstlineno gibt an, dass die erste Zeile der Funktion in Zeile 8 des entsprechenden Python-Codes erscheint.
Detaillierte Analyse des Flag-Felds
Wir verwenden speziell den Quellcode von Python3.5 für die Analyse. Die spezifische Implementierung der virtuellen cpython-Maschine lautet wie folgt (Include/code.h):
/* Masks for co_flags above */ #define CO_OPTIMIZED 0x0001 #define CO_NEWLOCALS 0x0002 #define CO_VARARGS 0x0004 #define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 #define CO_GENERATOR 0x0020 /* The CO_NOFREE flag is set if there are no free or cell variables. This information is redundant, but it allows a single flag test to determine whether there is any extra work to be done when the call frame it setup. */ #define CO_NOFREE 0x0040 /* The CO_COROUTINE flag is set for coroutine functions (defined with ``async def`` keywords) */ #define CO_COROUTINE 0x0080 #define CO_ITERABLE_COROUTINE 0x0100
Wenn das Flag-Feld und Jede der oben genannten Makrodefinitionen führt die &-Operation aus. Wenn das Ergebnis größer als 0 ist, bedeutet dies, dass die entsprechenden Bedingungen erfüllt sind.
Die obige Makrodefinition hat folgende Bedeutung:
CO_OPTIMIZED Dieses Feld zeigt an, dass das Codeobjekt optimiert ist und lokal von der Funktion definierte Variablen verwendet.
CO_NEWLOCALS, die Bedeutung dieses Feldes besteht darin, dass beim Ausführen des Codes dieses Codeobjekts ein Diktatobjekt für das f_locals-Objekt im Stapelrahmen erstellt wird.
CO_VARARGS gibt an, ob dieses Codeobjekt Positionsparameter enthält.
CO_VARKEYWORDS gibt an, ob dieses Codeobjekt Schlüsselwortparameter enthält.
CO_NESTED, was darauf hinweist, dass dieses Codeobjekt eine verschachtelte Funktion ist.
CO_GENERATOR, was anzeigt, dass dieses Codeobjekt ein Generator ist.
CO_COROUTINE, was darauf hinweist, dass dieses Codeobjekt eine Coroutine-Funktion ist.
CO_ITERABLE_COROUTINE, was anzeigt, dass das Codeobjekt eine iterierbare Coroutine-Funktion ist.
CO_NOFREE, das bedeutet, dass es keine Freevars und Cellvars gibt, das heißt, es gibt keinen Funktionsabschluss.
Jetzt analysieren wir die Flags der vorherigen Funktion test_co01. Der entsprechende Wert ist gleich 0x43, was bedeutet, dass diese Funktion drei Merkmale erfüllt: CO_NEWLOCALS, CO_OPTIMIZED und CO_NOFREE.
freevars & cellvars
我们使用下面的函数来对这两个字段进行分析:
def test_co02(): a = 1 b = 2 def g(): return a + b return a + b + g()
上面的函数的信息如下所示(完整代码见co02):
code argcount 0 nlocals 1 stacksize 3 flags 0003 0x3 code b'640100890000640200890100870000870100660200640300640400860000' b'7d0000880000880100177c00008300001753' 15 0 LOAD_CONST 1 (1) 3 STORE_DEREF 0 (a) 16 6 LOAD_CONST 2 (2) 9 STORE_DEREF 1 (b) 18 12 LOAD_CLOSURE 0 (a) 15 LOAD_CLOSURE 1 (b) 18 BUILD_TUPLE 2 21 LOAD_CONST 3 (<code object g at 0x7f133ff496f0, file "/tmp/pycharm_project_396/co01.py", line 18>) 24 LOAD_CONST 4 ('test_co02.<locals>.g') 27 MAKE_CLOSURE 0 30 STORE_FAST 0 (g) 20 33 LOAD_DEREF 0 (a) 36 LOAD_DEREF 1 (b) 39 BINARY_ADD 40 LOAD_FAST 0 (g) 43 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 46 BINARY_ADD 47 RETURN_VALUE consts None 1 2 code argcount 0 nlocals 0 stacksize 2 flags 0013 0x13 code b'8800008801001753' 19 0 LOAD_DEREF 0 (a) 3 LOAD_DEREF 1 (b) 6 BINARY_ADD 7 RETURN_VALUE consts None names () varnames () freevars ('a', 'b') cellvars () filename '/tmp/pycharm_project_396/co01.py' name 'g' firstlineno 18 lnotab b'0001' 'test_co02.<locals>.g' names () varnames ('g',) freevars () cellvars ('a', 'b') filename '/tmp/pycharm_project_396/co01.py' name 'test_co02' firstlineno 14 lnotab b'0001060106021502'
从上面的输出我们可以看到的是,函数 test_co02 的 cellvars 为 ('a', 'b'),函数 g 的 freevars 为 ('a', 'b'),cellvars 表示在其他函数当中会使用本地定义的变量,freevars 表示本地会使用其他函数定义的变量。
再来分析一下函数 test_co02 的 flags,他的 flags 等于 0x3 因为有闭包的存在因此 flags 不会存在 CO_NOFREE,也就是少了值 0x0040 。
stacksize
这个字段存储的是在函数在被虚拟机执行的时候所需要的最大的栈空间的大小,这也是一种优化手段,因为在知道所需要的最大的栈空间,所以可以在函数执行的时候直接分配指定大小的空间不需要在函数执行的时候再去重新扩容。
def test_stack(): a = 1 b = 2 return a + b
上面的代码相关字节码等信息如下所示:
code argcount 0 nlocals 2 stacksize 2 flags 0043 0x43 code b'6401007d00006402007d01007c00007c01001753' # 字节码指令 # 字节码指令参数 # 参数对应的值 24 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (a) 25 6 LOAD_CONST 2 (2) 9 STORE_FAST 1 (b) 26 12 LOAD_FAST 0 (a) 15 LOAD_FAST 1 (b) 18 BINARY_ADD 19 RETURN_VALUE consts None # 下标等于 0 的常量 1 # 下标等于 1 的常量 2 # 下标等于 2 的常量 names () varnames ('a', 'b') freevars () cellvars ()
我们现在来模拟一下执行过程,在模拟之前我们首先来了解一下上面几条字节码的作用:
LOAD_CONST,将常量表当中的下标等于 i 个对象加载到栈当中,对应上面的代码 LOAD_CONST 的参数 i = 1。因此加载测常量等于 1 。因此现在栈空间如下所示:
STORE_FAST,将栈顶元素弹出并且保存到 co_varnames 对应的下标当中,根据上面的字节码参数等于 0 ,因此将 1 保存到 co_varnames[0] 对应的对象当中。
LOAD_CONST,将下标等于 2 的常量加载进入栈中。
STORE_FAST,将栈顶元素弹出,并且保存到 varnames 下标为 1 的对象。
LOAD_FAST,是取出 co_varnames 对应下标的数据,并且将其压入栈中。我们直接连续执行两个 LOAD_FAST 之后栈空间的布局如下:
BINARY_ADD,这个字节码指令是将栈空间的两个栈顶元素弹出,然后将两个数据进行相加操作,然后将相加得到的结果重新压入栈中。
RETURN_VALUE,将栈顶元素弹出并且作为返回值返回。
从上面的整个执行过程来看整个栈空间使用的最大的空间长度为 2 ,因此 stacksize = 2 。
Das obige ist der detaillierte Inhalt vonWelche Rolle spielt das Codeobjekt in der virtuellen Python-Maschine?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



MySQL hat eine kostenlose Community -Version und eine kostenpflichtige Enterprise -Version. Die Community -Version kann kostenlos verwendet und geändert werden, die Unterstützung ist jedoch begrenzt und für Anwendungen mit geringen Stabilitätsanforderungen und starken technischen Funktionen geeignet. Die Enterprise Edition bietet umfassende kommerzielle Unterstützung für Anwendungen, die eine stabile, zuverlässige Hochleistungsdatenbank erfordern und bereit sind, Unterstützung zu bezahlen. Zu den Faktoren, die bei der Auswahl einer Version berücksichtigt werden, gehören Kritikalität, Budgetierung und technische Fähigkeiten von Anwendungen. Es gibt keine perfekte Option, nur die am besten geeignete Option, und Sie müssen die spezifische Situation sorgfältig auswählen.

Der Artikel führt den Betrieb der MySQL -Datenbank vor. Zunächst müssen Sie einen MySQL -Client wie MySQLworkBench oder Befehlszeilen -Client installieren. 1. Verwenden Sie den Befehl mySQL-uroot-P, um eine Verbindung zum Server herzustellen und sich mit dem Stammkonto-Passwort anzumelden. 2. Verwenden Sie die Erstellung von Createdatabase, um eine Datenbank zu erstellen, und verwenden Sie eine Datenbank aus. 3.. Verwenden Sie CreateTable, um eine Tabelle zu erstellen, Felder und Datentypen zu definieren. 4. Verwenden Sie InsertInto, um Daten einzulegen, Daten abzufragen, Daten nach Aktualisierung zu aktualisieren und Daten nach Löschen zu löschen. Nur indem Sie diese Schritte beherrschen, lernen, mit gemeinsamen Problemen umzugehen und die Datenbankleistung zu optimieren, können Sie MySQL effizient verwenden.

Die Hauptgründe für den Fehler bei MySQL -Installationsfehlern sind: 1. Erlaubnisprobleme, Sie müssen als Administrator ausgeführt oder den Sudo -Befehl verwenden. 2. Die Abhängigkeiten fehlen, und Sie müssen relevante Entwicklungspakete installieren. 3. Portkonflikte müssen Sie das Programm schließen, das Port 3306 einnimmt, oder die Konfigurationsdatei ändern. 4. Das Installationspaket ist beschädigt. Sie müssen die Integrität herunterladen und überprüfen. 5. Die Umgebungsvariable ist falsch konfiguriert und die Umgebungsvariablen müssen korrekt entsprechend dem Betriebssystem konfiguriert werden. Lösen Sie diese Probleme und überprüfen Sie jeden Schritt sorgfältig, um MySQL erfolgreich zu installieren.

Die MySQL -Download -Datei ist beschädigt. Was soll ich tun? Wenn Sie MySQL herunterladen, können Sie die Korruption der Datei begegnen. Es ist heutzutage wirklich nicht einfach! In diesem Artikel wird darüber gesprochen, wie dieses Problem gelöst werden kann, damit jeder Umwege vermeiden kann. Nach dem Lesen können Sie nicht nur das beschädigte MySQL -Installationspaket reparieren, sondern auch ein tieferes Verständnis des Download- und Installationsprozesses haben, um zu vermeiden, dass Sie in Zukunft stecken bleiben. Lassen Sie uns zunächst darüber sprechen, warum das Herunterladen von Dateien beschädigt wird. Dafür gibt es viele Gründe. Netzwerkprobleme sind der Schuldige. Unterbrechung des Download -Prozesses und der Instabilität im Netzwerk kann zu einer Korruption von Dateien führen. Es gibt auch das Problem mit der Download -Quelle selbst. Die Serverdatei selbst ist gebrochen und natürlich auch unterbrochen, wenn Sie sie herunterladen. Darüber hinaus kann das übermäßige "leidenschaftliche" Scannen einer Antiviren -Software auch zu einer Beschädigung von Dateien führen. Diagnoseproblem: Stellen Sie fest, ob die Datei wirklich beschädigt ist

MySQL hat sich geweigert, anzufangen? Nicht in Panik, lass es uns ausprobieren! Viele Freunde stellten fest, dass der Service nach der Installation von MySQL nicht begonnen werden konnte, und sie waren so ängstlich! Mach dir keine Sorgen, dieser Artikel wird dich dazu bringen, ruhig damit umzugehen und den Mastermind dahinter herauszufinden! Nachdem Sie es gelesen haben, können Sie dieses Problem nicht nur lösen, sondern auch Ihr Verständnis von MySQL -Diensten und Ihren Ideen zur Fehlerbehebungsproblemen verbessern und zu einem leistungsstärkeren Datenbankadministrator werden! Der MySQL -Dienst startete nicht und es gibt viele Gründe, von einfachen Konfigurationsfehlern bis hin zu komplexen Systemproblemen. Beginnen wir mit den häufigsten Aspekten. Grundkenntnisse: Eine kurze Beschreibung des Service -Startup -Prozesses MySQL Service Startup. Einfach ausgedrückt, lädt das Betriebssystem MySQL-bezogene Dateien und startet dann den MySQL-Daemon. Dies beinhaltet die Konfiguration

MySQL kann ohne Netzwerkverbindungen für die grundlegende Datenspeicherung und -verwaltung ausgeführt werden. Für die Interaktion mit anderen Systemen, Remotezugriff oder Verwendung erweiterte Funktionen wie Replikation und Clustering ist jedoch eine Netzwerkverbindung erforderlich. Darüber hinaus sind Sicherheitsmaßnahmen (wie Firewalls), Leistungsoptimierung (Wählen Sie die richtige Netzwerkverbindung) und die Datensicherung für die Verbindung zum Internet von entscheidender Bedeutung.

Die MySQL-Datenbankleistung Optimierungshandbuch In ressourcenintensiven Anwendungen spielt die MySQL-Datenbank eine entscheidende Rolle und ist für die Verwaltung massiver Transaktionen verantwortlich. Mit der Erweiterung der Anwendung werden jedoch die Datenbankleistung Engpässe häufig zu einer Einschränkung. In diesem Artikel werden eine Reihe effektiver Strategien zur Leistungsoptimierung von MySQL -Leistung untersucht, um sicherzustellen, dass Ihre Anwendung unter hohen Lasten effizient und reaktionsschnell bleibt. Wir werden tatsächliche Fälle kombinieren, um eingehende Schlüsseltechnologien wie Indexierung, Abfrageoptimierung, Datenbankdesign und Caching zu erklären. 1. Das Design der Datenbankarchitektur und die optimierte Datenbankarchitektur sind der Eckpfeiler der MySQL -Leistungsoptimierung. Hier sind einige Kernprinzipien: Die Auswahl des richtigen Datentyps und die Auswahl des kleinsten Datentyps, der den Anforderungen entspricht, kann nicht nur Speicherplatz speichern, sondern auch die Datenverarbeitungsgeschwindigkeit verbessern.

Die MySQL -Leistungsoptimierung muss von drei Aspekten beginnen: Installationskonfiguration, Indexierung und Abfrageoptimierung, Überwachung und Abstimmung. 1. Nach der Installation müssen Sie die my.cnf -Datei entsprechend der Serverkonfiguration anpassen, z. 2. Erstellen Sie einen geeigneten Index, um übermäßige Indizes zu vermeiden und Abfrageanweisungen zu optimieren, z. B. den Befehl Erklärung zur Analyse des Ausführungsplans; 3. Verwenden Sie das eigene Überwachungstool von MySQL (ShowProcessList, Showstatus), um die Datenbankgesundheit zu überwachen und die Datenbank regelmäßig zu sichern und zu organisieren. Nur durch kontinuierliche Optimierung dieser Schritte kann die Leistung der MySQL -Datenbank verbessert werden.
