Récemment, j'ai appris la programmation réseau Python. Lors de l'écriture de code de communication socket simple, j'ai rencontré l'utilisation du module struct. À ce moment-là, je n'étais pas sûr de ce qu'il faisait et de ce qu'il faisait. Informations pertinentes et en avoir une compréhension approximative.Cet article L'article présente principalement le fonctionnement du flux d'octets/flux binaire par le module struct en Python. Les amis dans le besoin peuvent s'y référer.
Avant-propos
Récemment, Python est utilisé pour analyser l'ensemble de données MNIST au format de fichier IDX, et le fichier binaire doit être lu, dans lequel j'utilise est le module struct. J'ai consulté de nombreux tutoriels sur Internet et ils étaient tous très bons, mais pas très conviviaux pour les novices, j'ai donc réorganisé quelques notes pour vous aider à démarrer rapidement.
Remarque : Les quatre termes suivants dans le didacticiel sont synonymes : flux binaire, tableau binaire, flux d'octets, tableau d'octets
Démarrez rapidement
Dans le module struct, convertissez un nombre entier, un nombre à virgule flottante ou un flux de caractères (tableau de caractères) en un flux d'octets (tableau de sections de mots) , vous devez utiliser la chaîne de format fmt pour indiquer au module struct quel type d'objet à convertir, par exemple, un nombre entier est 'i', un nombre à virgule flottante est 'f' et un caractère de code ascii est 's. '.
def demo1(): # 使用bin_buf = struct.pack(fmt, buf)将buf为二进制数组bin_buf # 使用buf = struct.unpack(fmt, bin_buf)将bin_buf二进制数组反转换回buf # 整型数 -> 二进制流 buf1 = 256 bin_buf1 = struct.pack('i', buf1) # 'i'代表'integer' ret1 = struct.unpack('i', bin_buf1) print bin_buf1, ' <====> ', ret1 # 浮点数 -> 二进制流 buf2 = 3.1415 bin_buf2 = struct.pack('d', buf2) # 'd'代表'double' ret2 = struct.unpack('d', bin_buf2) print bin_buf2, ' <====> ', ret2 # 字符串 -> 二进制流 buf3 = 'Hello World' bin_buf3 = struct.pack('11s', buf3) # '11s'代表长度为11的'string'字符数组 ret3 = struct.unpack('11s', bin_buf3) print bin_buf3, ' <====> ', ret3 # 结构体 -> 二进制流 # 假设有一个结构体 # struct header { # int buf1; # double buf2; # char buf3[11]; # } bin_buf_all = struct.pack('id11s', buf1, buf2, buf3) ret_all = struct.unpack('id11s', bin_buf_all) print bin_buf_all, ' <====> ', ret_all
Les résultats de sortie sont les suivants :
résultats de sortie demo1
Explication détaillée du module struct
Fonctions principales
Les trois fonctions les plus importantes du module struct sont pack()
, unpack()
, calcsize()
# 按照给定的格式化字符串,把数据封装成字符串(实际上是类似于c结构体的字节流) string = struct.pack(fmt, v1, v2, ...) # 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple tuple = unpack(fmt, string) # 计算给定的格式(fmt)占用多少字节的内存 offset = calcsize(fmt)
Formater la chaîne dans la structure
Formats pris en charge dans struct Comme le montre le tableau suivant :
Format | C Type | Python | 字节数 |
---|---|---|---|
x | pad byte | no value | 1 |
c | char | string 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 or lon | 4 |
l | long | integer | 4 |
L | unsigned long | long | 4 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | 1 |
p | char[] | string | 1 |
P | void * | long |
Note 1 : q et Q ne sont intéressants que lorsque la machine supporte le fonctionnement 64 bits
Note 2 : Chacun Il peut y avoir un nombre avant le format, indiquant le nombre
Note 3 : le format s représente une chaîne d'une certaine longueur, 4s représente une chaîne de longueur 4, mais p représente une chaîne de pascal
Note 4 : P est utilisé pour convertir un pointeur, sa longueur est liée à la longueur du mot machine
Note 5 : Le dernier peut être utilisé pour représenter le type pointeur, occupant 4 mots Section
Afin d'échanger des données avec des structures en c, il faut également considérer que certains compilateurs c ou c utilisent l'alignement d'octets, généralement en 32- systèmes de bits avec 4 octets. Par conséquent, la structure est convertie selon l'ordre des octets de la machine locale. Le premier caractère du format peut être utilisé pour modifier l'alignement. La définition est la suivante :
<.>
Character | Byte order | Size and alignment |
---|---|---|
@ | native | native 凑够4个字节 |
= | native | standard 按原字节数 |
little-endian | standard 按原字节数 | |
> | big-endian | standard 按原字节数 |
! | network (= big-endian) | standard 按原字节数 |