Strukturmodul in Python
Der Strukturmodul In Python ermöglicht Ihnen die Arbeit mit Binärdaten, indem es Funktionen zum Konvertieren zwischen Python-Werten und Binärdaten im C-Stil bereitstellt. Dies ist besonders nützlich, wenn es um binäre Dateiformate oder Netzwerkprotokolle geht. Zu den wichtigsten Funktionen gehören:
- Verpackung Konvertieren Sie Python-Werte in Binärdaten (Bytes).
- Auspacken Konvertieren Sie Binärdaten zurück in Python-Werte.
- Zeichenfolgen formatieren Definieren Sie mithilfe von Formatcodes, wie Daten gepackt/entpackt werden (z. B. i für Ganzzahlen, f für Floats).
Methoden in struct.pack()
1.Struct.pack(): Es konvertiert Python-Werte in ein gepacktes Binärformat. Der Formatstring (fmt) gibt das Layout der gepackten Daten an und die nachfolgenden Werte (v1 v2 ...) werden gemäß diesem Format gepackt. Syntax:
struct.pack(fmt v1 v2 ...)
- fmt : Eine Formatzeichenfolge, die angibt, wie die Daten gepackt werden.
- v1 v2 ...: Die Werte, die gemäß dem angegebenen Format gepackt werden.
import struct # pack values into binary var = struct . pack ( 'hhl' 1 2 3 ) print ( var ) var = struct . pack ( 'iii' 1 2 3 ) print ( var )
Ausgabe
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'
Erklärung: 'hhl' bedeutet zwei kurze Ganzzahlen (h jeweils 2 Bytes), gefolgt von einer langen Ganzzahl (l normalerweise 4 oder 8 Bytes, je nach Plattform). 'iii' packt drei 4-Byte-Ganzzahlen. Die Ausgabe erfolgt in Bytes (b''), die die binäre Kodierung der Werte darstellen.
2.struct.unpack(): Es konvertiert gepackte Binärdaten zurück in Python-Werte. Es benötigt einen Formatstring (fmt) und einen gepackten Binärstring und gibt ein Tupel entpackter Werte zurück. Syntax:
struct.unpack(fmt string)
- fmt: Eine Formatzeichenfolge, die angibt, wie die Daten entpackt werden sollen.
- Zeichenfolge: Die gepackten Binärdaten, die entpackt werden müssen.
import struct var = struct . pack ( '?hil' True 2 5 445 ) print ( var ) tup = struct . unpack ( '?hil' var ) print ( tup ) var = struct . pack ( 'qf' 5 2.3 ) print ( var ) tup = struct . unpack ( 'qf' var ) print ( tup )
Ausgabe
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)
Erläuterung: In diesem Beispiel werden zunächst ein boolescher Wert (?), ein kurzer Wert (h), eine Ganzzahl (i) und ein langer Wert (l) in Bytes gepackt. Dann wird struct.unpack() verwendet, um es wieder in Python-Werte umzuwandeln. Der zweite Teil packt einen Long-Long-Integer (q) und einen Float (f) und entpackt sie dann wieder. Beachten Sie, wie 2,3 aufgrund der Float-Präzision zu 2,299999952 wird.
3. struct.calcsize(): Es gibt die Größe (in Bytes) einer Struktur zurück, die der Formatzeichenfolge entspricht. Dies ist hilfreich, um zu bestimmen, wie viel Speicherplatz zum Speichern gepackter Daten erforderlich ist. Syntax:
struct.calcsize(fmt)
- fmt: Eine Formatzeichenfolge, die das Datenlayout angibt.
import struct print ( struct . calcsize ( '?hil' )) print ( struct . calcsize ( 'qf' ))
Ausgabe
16 12
Erklärung: '?hil' erfordert 16 Bytes und 'qf' benötigt je nach Ausrichtung und Plattform 12 Bytes.
4. struct.pack_into() und struct.unpack_from(): Mit diesen Methoden können Sie Daten ab einem bestimmten Offset direkt in bzw. aus einem Puffer packen und entpacken. Diese sind besonders nützlich, wenn Sie mit vorab zugewiesenen Speicherpuffern arbeiten oder mit im Speicher gespeicherten Binärdaten arbeiten.
Syntax für struct.pack_into():
struct.pack_into(fmt buffer offset v1 v2 ...)
- fmt: Eine Formatzeichenfolge, die das Datenlayout angibt.
- Puffer: Ein beschreibbarer Puffer (z. B. ctypes.create_string_buffer).
- Offset: Die Startposition im Puffer, an der das Packen beginnt.
- v1 v2 ...: Die Werte, die in den Puffer gepackt werden sollen.
Syntax für struct.unpack_from():
struct.unpack_from(fmt buffer offset=0)
- fmt: Eine Formatzeichenfolge, die das Datenlayout angibt.
- Puffer: Der Puffer, der die gepackten Daten enthält.
- Versatz: Die Ausgangsposition, von der aus das Auspacken beginnt (optional)
import struct import ctypes # Allocate buffer size = struct . calcsize ( 'hhl' ) buff = ctypes . create_string_buffer ( size ) # Pack into buffer struct . pack_into ( 'hhl' buff 0 2 2 3 ) # Unpack from buffer res = struct . unpack_from ( 'hhl' buff 0 ) print ( res )
Ausgabe
(2 2 3)
Erläuterung: Hier wird mithilfe von ctypes ein Puffer erstellt. struct.pack_into() fügt die Werte am angegebenen Offset (in diesem Fall 0) in diesen Puffer ein. struct.unpack_from() liest dann die Daten aus dem Puffer zurück.
Auswirkung der Formatreihenfolge
Die Reihenfolge der Formatzeichen kann aufgrund von Auffüllung und Ausrichtung die gepackte Ausgabe verändern. Dies wirkt sich sowohl auf den Byteinhalt als auch auf die Größe des Ergebnisses aus.
Python import struct var = struct . pack ( 'bi' 56 0x12131415 ) print ( var ) print ( struct . calcsize ( 'bi' )) var = struct . pack ( 'ib' 0x12131415 56 ) print ( var ) print ( struct . calcsize ( 'ib' ))
Ausgabe
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5
Erläuterung: 'bi' (byte int) könnte ein Auffüllen nach dem Byte enthalten, wohingegen 'ib' (int byte) braucht es nicht. Der Größenunterschied (8 vs. 5) zeigt, wie sich die Ausrichtung auf das Speicherlayout auswirkt.
Umgang mit Fehlern
Wenn bei struct.pack() der falsche Datentyp verwendet wird, tritt ein struct.error auf. Verwenden Sie Try-Except, um solche Fälle sicher zu handhaben.
Python import struct try : struct . pack ( 'h' 'invalid' ) # Wrong type 'invalid' is a string but 'h' expects an integer except struct . error as e : print ( f 'Struct Error: { e } ' )
Ausgabe
Struct Error: required argument is not an integer
Erläuterung: Dies zeigt die Fehlerbehandlung bei der Verwendung von struct. „h“ erwartet eine kurze Ganzzahl, aber es wird eine Zeichenfolge („ungültig“) angegeben, die einen Strukturfehler verursacht. Der Try-Exception-Block erfasst den Fehler und gibt eine aussagekräftige Meldung aus.
Referenz https://docs.python.org/2/library/struct.html
Quiz erstellen