首頁  >  文章  >  後端開發  >  Python中struct模組對位元組流/二進位流的操作教程

Python中struct模組對位元組流/二進位流的操作教程

高洛峰
高洛峰原創
2017-02-20 10:46:061771瀏覽

最近在學習python網路程式設計這一塊,在寫簡單的socket通訊程式碼時,遇到了struct這個模組的使用,當時不太清楚這到底有和作用,後來查閱了相關資料大概了解了,這篇文章就主要介紹了Python中struct模組對位元組流/二進位流的操作,需要的朋友可以參考借鑒。

前言

最近使用Python解析IDX檔案格式的MNIST資料集,需要對二進位進行讀取操作,其中我使用的是struct模組。查了網路上挺多教程都寫的挺好的,不過對新手不是很友好,所以我重新整理了一些筆記以供快速上手。

註:教程中以下四個名詞同義:二進位流、二進位數組、位元組流、位元組數組

快速上手

在struct模組中,將一個整數數字、浮點型數字或字元流(字元陣列)轉換為位元組流(字節數組)時,需要使用格式化字串fmt告訴struct模組被轉換的物件是什麼類型,例如整數數字是'i',浮點型數字是'f',一個ascii碼字元是'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, &#39; <====> &#39;, ret1

 # 浮点数 -> 二进制流
 buf2 = 3.1415
 bin_buf2 = struct.pack(&#39;d&#39;, buf2) # &#39;d&#39;代表&#39;double&#39;
 ret2 = struct.unpack(&#39;d&#39;, bin_buf2)
 print bin_buf2, &#39; <====> &#39;, ret2

 # 字符串 -> 二进制流
 buf3 = &#39;Hello World&#39;
 bin_buf3 = struct.pack(&#39;11s&#39;, buf3) # &#39;11s&#39;代表长度为11的&#39;string&#39;字符数组
 ret3 = struct.unpack(&#39;11s&#39;, bin_buf3)
 print bin_buf3, &#39; <====> &#39;, ret3

 # 结构体 -> 二进制流
 # 假设有一个结构体
 # struct header {
 # int buf1;
 # double buf2;
 # char buf3[11];
 # }
 bin_buf_all = struct.pack(&#39;id11s&#39;, buf1, buf2, buf3)
 ret_all = struct.unpack(&#39;id11s&#39;, bin_buf_all)
 print bin_buf_all, &#39; <====> &#39;, ret_all

輸出結果如下:

Python中struct模組對位元組流/二進位流的操作教程
demo1輸出結果

詳解struct模組

主要函式

struct模組中最重要的三個函式是pack() , unpack() , calcsize()

# 按照给定的格式化字符串,把数据封装成字符串(实际上是类似于c结构体的字节流)
string = struct.pack(fmt, v1, v2, ...)

# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
tuple = unpack(fmt, string)

# 计算给定的格式(fmt)占用多少字节的内存
offset = calcsize(fmt)

struct中的格式化字串

struct中支援的格式如下表:


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  

      註1:q和Q只在機器支援64位元作業時有意思

      註2:每個格式前可以有一個數字,表示個數

      註3:s格式表示一定長度的字串,4s表示長度為4的字串,但是p表示的是pascal字串

註4:P用來轉換一個指針,其長度和機器字長相關

      註5:最後一個可以用來表示指針類型的,佔4個位元組

為了同c中的結構體交換數據,還要考慮有的c或c++編譯器使用了位元組對齊,通常是以4個位元組為單位的32位元系統,故而struct根據本地機器位元組順序轉換.可以用格式中的第一個字元來改變對齊方式.定義如下:


Character Byte order Size and alignment
@ native native 湊夠4個位元組
= native standard 依原始位元組數
little- endian standard 依原位元組數
> big-endian standard 依原位元組數
! network (= big-endian) standard 以原始位元組數

使用方法是放在fmt的第一個位置,就像'@5s6sif'

更多Python中struct模組對字節流/二進制流的操作教程相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn