Das Python struct-Modul wird verwendet, um eine einfache Python-Schnittstelle für den Zugriff auf und die Manipulation von Cs Struktur-Datentyp bereitzustellen. Dies kann ein praktisches Werkzeug sein, wenn Sie jemals mit C-Code zu tun haben und keine Zeit haben, Werkzeuge in C zu schreiben, da es eine Low-Level-Sprache ist.
Dieses Modul kann Python-Werte in eine C-Struktur konvertieren und umgekehrt. Die C-Struktur wird als Python-Bytes-Objekt verwendet, da es in C kein Objekt gibt, sondern nur bytegroße Datenstrukturen.
Lassen Sie uns verstehen, wie wir dieses Modul verwenden können, um eine Python-Schnittstelle zu C-Strukturen zu haben.
Methoden des Moduls Python struct
Da wir es in diesem Modul mit C-Strukturen zu tun haben, wollen wir uns einige der Funktionen ansehen, die uns dieses Modul zur Verfügung stellt.
struct.pack()
Dies wird verwendet, um Elemente in eine Python-Byte-Zeichenkette (Byte-Objekt) zu packen. Da die Art der Speicherung auf Bytes basiert, können C-basierte Programme die Ausgabe von pack()
aus einem Python-Programm verwenden.
Format: struct.pack(format, v1, v2, …)
v1
v2
, … sind die Werte, die in das Byte-Objekt gepackt werden. Sie stellen die Feldwerte für die C-Struktur dar. Da eine C-Struktur mit n
-Feldern genau n
-Werte haben muss, müssen die Argumente genau mit den vom Format geforderten Werten übereinstimmen.
Hier verweist format
auf das Format der Packung. Dieses wird benötigt, da wir den Datentyp der Byte-Zeichenkette angeben müssen, wie er bei C-Code verwendet wird. Die folgende Tabelle listet die gängigsten Werte für format
auf. Wir benötigen ein Format pro Wert, um dessen Datentyp anzugeben.
Format | C Datentyp | Python-Typ |
c |
char | ein String der Länge 1 |
? |
_Bool | bool |
h |
kurz | ganzzahlig |
l |
lang | ganzzahlig |
i |
int | ganzzahlig |
f |
float | float |
d |
double | float |
s |
char | string |
Lassen Sie uns dies anhand einiger Beispiele verstehen.
Das folgende Snippet speichert die 3 Integer 1, 2 und 3 in einem Byte-Objekt mit pack()
. Da die Größe eines Integers auf meinem Rechner 4 Bytes beträgt, sehen Sie 3 Blöcke von 4 Bytes, die in C 3 Integern entsprechen.
import struct# We pack 3 integers, so 'iii' is requiredvariable = struct.pack('iii', 1, 2, 3)print(type(variable), variable)variable_2 = struct.pack('iic', 1, 2, b'A')print('\n', variable_2)
Ausgabe
<class 'bytes'> b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'b'\x01\x00\x00\x00\x02\x00\x00\x00A'
Wenn der passende Typ nicht übergeben wird, wird die Ausnahme struct.error
vom Python-Strukturmodul ausgelöst.
import struct# Error!! Incorrect datatype assignmentvariable = struct.pack('ccc', 1, 2, 3)print(type(variable), variable)
Ausgabe
struct.error: char format requires a bytes object of length 1
struct.unpack()
Diese Funktion des Python-Moduls struct packt den gepackten Wert in seine ursprüngliche Darstellung nach einem geeigneten Format aus. Sie gibt ein Tupel zurück, dessen Größe der Anzahl der übergebenen Werte entspricht, da das Byte-Objekt entpackt wird, um die Elemente zu erhalten.
Format: struct.unpack(format, string)
Das entpackt das Byte string
gemäß der format
Formatangabe.
Das ist die Umkehrung von struct.pack()
. Nehmen wir eine der alten Byte-Zeichenketten, die wir damit erzeugt haben, und versuchen wir, mit unpack()
die übergebenen Python-Werte zurückzubekommen.
import structbyte_str = b'\x01\x00\x00\x00\x02\x00\x00\x00A'# Using the same format specifier as before, since# we want to get Python values for the same byte-stringtuple_vals = struct.unpack('iic', byte_str)print(tuple_vals)
Ausgabe
(1, 2, b'A')
Wie Sie sehen können, ist es tatsächlich so, können wir unsere alten Python-Werte aus diesem Tupel packen, vorausgesetzt, wir verwenden den gleichen Format-Spezifizierer für sowohl pack()
als auch unpack()
.
struct.calcsize()
Diese Funktion liefert die Gesamtgröße der String-Repräsentation der struct unter Verwendung eines gegebenen Formatspezifizierers.
Format: struct.calcsize(fmt)
import structprint('C Integer Size in Bytes:', struct.calcsize('i'))print('Size of 3 characters in Bytes:', struct.calcsize('ccc'))
Ausgabe
C Integer Size in Bytes: 4Size of 3 characters in Bytes: 3
struct.pack_into()
Diese Funktion dient dazu, Werte in einen Python-Stringpuffer zu packen, der im Modul ctypes
verfügbar ist.
Format: struct.pack_into(fmt, buffer, offset, v1, v2, …)
Hier bezieht sich fmt
wie immer auf den Format-Spezifikator. buffer
ist der String-Puffer, der nun die angegebenen gepackten Werte enthalten wird. Sie können auch eine offset
Stelle von der Basisadresse aus angeben, von der aus gepackt werden soll.
Dies gibt keinen Wert zurück, sondern speichert die Werte einfach in den buffer
String.
import struct import ctypes # We will create a string buffer having a size# equal to that of a struct with 'iic' values.buf_size = struct.calcsize('iic') # Create the string bufferbuff = ctypes.create_string_buffer(buf_size) # struct.pack() returns the packed data struct.pack_into('iic', buff, 0, 1, 2, b'A')print(buff)# Display the contents of the bufferprint(buff)
Ausgabe
<ctypes.c_char_Array_9 object at 0x7f4bccef1040>b'\x01\x00\x00\x00\x02\x00\x00\x00A'
Als Ergebnis erhalten wir unsere gepackten Werte im Pufferstring.
struct.unpack_from()
Analog zu unpack()
gibt es ein Gegenstück zum Auspacken von Werten aus einem Pufferstring. Dies macht das Gegenteil von struct.pack_into()
.
Format: struct.unpack_from(fmt, buffer, offset)
Dies liefert ein Tupel von Werten, ähnlich wie struct.unpack()
.
import struct import ctypes # We will create a string buffer having a size# equal to that of a struct with 'iic' values.buf_size = struct.calcsize('iic') # Create the string bufferbuff = ctypes.create_string_buffer(buf_size) # struct.pack() returns the packed data struct.pack_into('iic', buff, 0, 1, 2, b'A')print(struct.unpack_from('iic', buff, 0))
Ausgabe
(1, 2, b'A')
Fazit
In diesem Artikel haben wir gelernt, wie man mit dem Python-Modul struct mit Struktur-Objekten vom Typ C umgeht.