Zawartość
- 1. Użycie modułu struct. Spakowane dane binarne
- 2. Podstawowe metody modułu struct
- 2.1. Metody pack() i unpack(). Pakowanie i rozpakowywanie danych
- 2.2. Metoda calcsize(). Rozmiar spakowanego obiektu
- 3. Formatowanie ciągów znaków
- 3.1. Ustawianie kolejności bajtów, rozmiaru i wyrównania na podstawie znaku formatu
- 3.2. Przykłady sformatowanych ciągów dla różnych typów danych
- Powiązane tematy
Szukaj innych stron:
1. Korzystanie z modułu struct. Spakowane dane binarne
Moduł struct w Pythonie służy do tworzenia i wyciągania spakowanych danych binarnych z łańcuchów. W module struct bajty danych są interpretowane jako spakowane dane binarne, które mogą być reprezentowane przez obiekty typu bytes lub bytearray.
Moduł zawiera narzędzia konwersji między wartościami Pythona a strukturami C, które są reprezentowane jako obiekty bajtowe Pythona. Takie konwersje są wykorzystywane w przetwarzaniu danych binarnych, które są przechowywane w plikach lub uzyskiwane z połączeń sieciowych itp.
Aby zapewnić zwarty opis struktur C i konwersję na wartości (z wartości) Pythona, używane są łańcuchy formatujące.
⇑
2. Podstawowe metody modułu struct
Moduł struct zawiera kilka podstawowych metod, których można użyć do pakowania i rozpakowywania danych.
2.1. Metody pack() i unpack(). Pakowanie i rozpakowywanie danych
Do pakowania i rozpakowywania danych służą metody pack(), unpack(). Proces pakowania/rozpakowywania realizowany jest zgodnie z łańcuchem formatu.
Zgodnie z dokumentacją, ogólna postać użycia metody pack() jest następująca
obj = struct.pack(format, v1, v2, ...)
where
- format – łańcuch formatu. Ciąg ten jest formowany zgodnie z zasadami określonymi w tablicach (patrz punkt 3);
- v1, v2, … – wartości (obiekty) do spakowania;
- obj – spakowany obiekt binarny.
Funkcja unpack() wykonuje operację odwrotną do pack(). Pozwala ona na uzyskanie obiektu źródłowego na podstawie obiektu spakowanego. Ogólna forma użycia funkcji jest następująca:
obj = struct.unpack(format, buffer)
here
- Bufor – bufor, do którego zapisywany jest obiekt, który został wcześniej spakowany przez funkcję pack(). Rozmiar tego obiektu musi być zgodny z rozmiarem określonym w format;
- format – ciąg formatu, na podstawie którego otrzymywany jest rozpakowany obiekt binarny obj;
- obj – obiekt wynikowy, który może być listą, krotką, zbiorem, słownikiem, itp.
Przy wywołaniu funkcji rozpakuj() ciąg formatu musi być zgodny z tym samym ciągiem, który został określony przez funkcję pakuj().
Przykład. W celu demonstracji przeprowadzane jest pakowanie/rozpakowywanie listy liczb.
# Module struct. Methods pack(), unpack()# Pack/unpack list of numbers# 1. Specified list of numbersLS = # 2. Include module structimport struct# 3. Pack list of numbers. Method pack()pack_obj = struct.pack('>4і', LS, LS, LS, LS)# 4. Display the object pack_objprint('pack_obj = ', pack_obj)# 5. Unpack list of numbers. Method unpack().# The result is a tuple T2T2 = struct.unpack('>4і', pack_obj) # T2 = (1, 3, 9, 12)# 6. Print the unpacked object T2print('T2 = ', T2)# 7. Convert tuple T2 to list LS2LS2 = list(T2) # LS2 = # 8. Display the list LS2print('LS2 = ', LS2)
wynik działania programu
pack_obj = b'\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\t\x00\x00\x00\x0c'T2 = (1, 3, 9, 12)LS2 =
⇑
2.2. Metoda calcsize(). Rozmiar spakowanego obiektu
Metoda calcsize() zwraca rozmiar obiektu utworzonego metodą pack().
Przykład.
# Module struct.# Method calcsize(). Determine the size of the packed object# 1. Include module structimport struct# 2. Determine the size of a packed list of numbers# 2.1. Specified list of floating point numbersLS = # 2.2. Pack list LS. Method pack()pack_obj = struct.pack('>3f', LS, LS, LS)# 2.3. Display the packed object pack_objprint('pack_obj = ', pack_obj)# 2.4. Display the size of pack_objsize = struct.calcsize('>3f') # size = 12print('size = ', size)# 3. Determine the size of a packed tuple of strings# 3.1. The specified tuple of two stringsTS = ( 'Hello', 'abcd')# 3.2. Pack the tuple TSpack_obj = struct.pack('<5s4s', TS.encode(), TS.encode())# 3.3. Display the packed objectprint('pack_obj = ', pack_obj)# 3.4. Display the size of packed tuplesize = struct.calcsize('<5s4s') # size = 9print('size = ', size)
Wynik działania programu
pack_obj = b'@8Q\xec@y\x99\x9a\xc1(\x00\x00'size = 12pack_obj = b'Helloabcd'size = 9
⇑
3. Formatowanie ciągów znaków
3.1. Ustawianie kolejności bajtów, rozmiaru i wyrównania na podstawie znaku formatu
W Pythonie sposób pakowania łańcucha jest określany na podstawie pierwszego znaku łańcucha formatu. Ten symbol definiuje:
- porządek bajtów, który jest tworzony przy użyciu znaków @, =, <>, !. Jeśli ten parametr nie jest określony, akceptowany jest symbol @;
- rozmiar w bajtach spakowanych danych. W tym przypadku w pierwszej kolejności używane są liczby, które na nią wskazują;
- wyrównanie, które jest ustawiane przez system.
Zgodnie z dokumentacją Pythona w łańcuchu formatu kolejność bajtów, rozmiar i wyrównanie są tworzone zgodnie z pierwszym znakiem formatu. Możliwe pierwsze znaki formatu są pokazane w poniższej tabeli.
Znak | Porządek bajtów | Size | Alignment |
@ | native (host dependent) | Native | Native |
= | native | standard | none |
< | little-endian | standard | none |
> | big-endian | standard | none |
! | network (= big-endian) | standard | none |
Wartość kolejności bajtów może być jedną z 4:
- native order. Ta kolejność może być albo little-endian albo big-endian. Kolejność ta jest określana przez system hosta;
- porządek typu little-endian. W tej kolejności najpierw przetwarzany jest bajt niski, a następnie bajt wysoki;
- porządek typu big-endian. W tym przypadku najpierw przetwarzany jest bajt wysoki, a następnie bajt niski;
- porządek sieciowy, który domyślnie ustawia się na porządek big-endian.
Wielkość spakowanych danych może być jedna z dwóch rzeczy:
- natywna – określana za pomocą instrukcji sizeof kompilatora C;
- standardowa – określana jest na podstawie znaku formatu zgodnie z poniższą tabelą.
Tabela. Określenie standardowego rozmiaru spakowanych danych w zależności od znaku formatu
Format | C Type | Python Typ | Rozmiar standardowy |
x | pad byte | brak wartości | |
c | char | bytes of length 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | bool | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsigned int | integer | 4 |
l | long | integer | 4 |
L | unsigned long | integer | 4 |
q | long long | integer | 8 |
Q | unsigned long long | integer | 8 |
n | ssize_t | integer | |
N | size_t | integer | |
e | float (format wykładniczy) | float | 2 |
f | float | float | 4 |
d | double | float | 8 |
s | char | bytes | |
p | char | bytes | |
P | void* | integer |
⇑
3.2. Przykłady ciągów sformatowanych dla różnych typów danych
.