Moduł Python struct jest używany do zapewnienia prostego interfejsu Pythona, aby uzyskać dostęp i manipulować typem danych struktury w C. Może to być przydatne narzędzie, jeśli kiedykolwiek będziesz miał do czynienia z kodem C i nie masz czasu na pisanie narzędzi w C, ponieważ jest to język niskiego poziomu. Może to być przydatne narzędzie, jeśli kiedykolwiek będziesz musiał poradzić sobie z kodem C i nie masz czasu na pisanie narzędzi w C, ponieważ jest to język niskiego poziomu.

Moduł ten może konwertować wartości Pythona na strukturę C i odwrotnie. Struktura C jest używana jako obiekt bajtowy Pythona, ponieważ w C nie ma nic, co można by nazwać obiektem; są tylko struktury danych wielkości bajtu.

Zrozummy, jak możemy użyć tego modułu, aby mieć interfejs Pythona do struktur C.

Metody modułu struct Pythona

W tym module, ponieważ zajmujemy się strukturami C, przyjrzyjmy się niektórym funkcjom, które ten moduł nam udostępnia.

struct.pack()

Służy do pakowania elementów w ciąg bajtów Pythona (obiekt byte). Ponieważ sposób przechowywania jest oparty na bajtach, programy oparte na C mogą używać danych wyjściowych pack(), z programu Pythona.

Format: struct.pack(format, v1, v2, …)

v1v2, … to wartości, które zostaną spakowane do obiektu bajtowego. Reprezentują one wartości pól dla struktury C. Ponieważ struktura C posiadająca n pola musi mieć dokładnie wartości n, argumenty muszą dokładnie odpowiadać wartościom wymaganym przez format.

Tutaj, format odnosi się do formatu pakowania. Jest to potrzebne, ponieważ musimy określić typ datatype ciągu bajtowego, tak jak jest to używane w kodzie C. Poniższa tabela zawiera listę najczęściej występujących wartości dla format. Potrzebujemy jednego formatu dla każdej wartości, aby określić jej typ danych.

Format C Datatype Typ Python
c char łańcuch o długości długości 1
? _Bool bool
h short integer
l long integer
i integer integer
f float float
d double float
s char string

Zrozummy to na kilku przykładach.

Poniższy snippet przechowuje 3 liczby całkowite 1, 2 i 3 w obiekcie bajtowym za pomocą pack(). Ponieważ rozmiar liczby całkowitej wynosi 4 bajty na mojej maszynie, widzisz 3 bloki po 4 bajty, które odpowiadają 3 liczbom całkowitym w C.

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)

Wyjście

<class 'bytes'> b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'b'\x01\x00\x00\x00\x02\x00\x00\x00A'

Jeśli nie zostanie przekazany odpowiedni typ, wyjątek struct.error zostanie podniesiony przez moduł struct Pythona.

import struct# Error!! Incorrect datatype assignmentvariable = struct.pack('ccc', 1, 2, 3)print(type(variable), variable)

Wyjście

struct.error: char format requires a bytes object of length 1

struct.unpack()

Ta funkcja modułu struct Pythona, rozpakowuje spakowaną wartość do jej oryginalnej reprezentacji zgodnie z odpowiednim formatem. Zwraca ona tuple o rozmiarze równym liczbie przekazanych wartości, ponieważ obiekt bajtowy jest rozpakowywany w celu uzyskania elementów.

Format: struct.unpack(format, string)

To rozpakowuje bajt string zgodnie ze specyfikatorem formatu format.

To jest odwrotność struct.pack(). Weźmy jeden ze starych ciągów bajtowych, które wyprodukowaliśmy przy użyciu tego i spróbujmy odzyskać wartości pythonowe przekazane do niego przy użyciu unpack().

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)

Output

(1, 2, b'A')

Jak widać, rzeczywiście, możemy uzyskać pakiet naszych starych wartości Pythona z tego tuple’a, pod warunkiem, że użyjemy tego samego specyfikatora formatu zarówno dla pack(), jak i unpack().

struct.calcsize()

Ta funkcja zwraca całkowity rozmiar reprezentacji String struktury przy użyciu podanego specyfikatora formatu, aby pobrać typy danych i obliczyć rozmiar.

Format: struct.calcsize(fmt)

import structprint('C Integer Size in Bytes:', struct.calcsize('i'))print('Size of 3 characters in Bytes:', struct.calcsize('ccc'))

Wyjście

C Integer Size in Bytes: 4Size of 3 characters in Bytes: 3

struct.pack_into()

Ta funkcja służy do pakowania wartości do bufora łańcuchowego Pythona, dostępnego w module ctypes.

Format: struct.pack_into(fmt, buffer, offset, v1, v2, …)

Tutaj fmt odnosi się do specyfikatora formatu, jak zawsze. buffer to bufor łańcuchowy, który będzie teraz zawierał spakowane wartości, określone. Możesz również określić offset lokalizację od adresu bazowego, od którego nastąpi pakowanie.

To nie zwraca żadnej wartości, a po prostu przechowuje wartości do łańcucha buffer.

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)

Wyjście

<ctypes.c_char_Array_9 object at 0x7f4bccef1040>b'\x01\x00\x00\x00\x02\x00\x00\x00A'

W końcu otrzymujemy nasze spakowane wartości w buforze string.

struct.unpack_from()

Podobnie jak w przypadku unpack(), istnieje odpowiednik dla rozpakowywania wartości z łańcucha buforowego. To robi odwrotność struct.pack_into().

Format: struct.unpack_from(fmt, buffer, offset)

To zwróci tuple wartości, podobne do 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))

Wyjście

(1, 2, b'A')

Podsumowanie

W tym artykule dowiedzieliśmy się o wykorzystaniu modułu struct w Pythonie do radzenia sobie z obiektami o strukturze typu C.

.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *