標籤:

Python中對位元組流/二進位流的操作:struct模塊簡易使用教程

關注微信號:人工智慧LeadAI(ID:atleadai)

查閱更為簡潔方便的分類文章以及最新的課程、產品信息,請移步至全新呈現的www.leadai.org

前言

前段時間使用Python解析IDX文件格式的MNIST數據集,需要對二進位文件進行讀取操作,其中我使用的是struct模塊。查了網上挺多教程都寫的挺好的,不過對新手不是很友好,所以我重新整理了一些筆記以供快速上手。

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

快速上手

在struct模塊中,將一個整型數字、浮點型數字或字元流(字元數組)轉換為位元組流(位元組數組)時,需要使用格式化字元串fmt告訴struct模塊被轉換的對象是什麼類型,比如整型數字是i,浮點型數字是f,一個ascii碼字元是s。

def demo1(): n# 使用bin_buf = struct.pack(fmt, buf)將buf為二進位數組bin_buf n# 使用buf = struct.unpack(fmt, bin_buf)將bin_buf二進位數組反轉換回buf n# 整型數 -> 二進位流 nbuf1 = 256 nbin_buf1 = struct.pack(i, buf1) # i代表integer nret1 = struct.unpack(i, bin_buf1) nprint bin_buf1, <====> , ret1 n# 浮點數 -> 二進位流 nbuf2 = 3.1415 nbin_buf2 = struct.pack(d, buf2) # d代表double nret2 = struct.unpack(d, bin_buf2) nprint bin_buf2, <====> , ret2 n# 字元串 -> 二進位流 nbuf3 = Hello World nbin_buf3 = struct.pack(11s, buf3) # 11s代表長度為11的string字元數組 nret3 = struct.unpack(11s, bin_buf3) nprint bin_buf3, <====> , ret3 n# 結構體 -> 二進位流 n# 假設有一個結構體 n# struct header { n# int buf1; n# double buf2; n# char buf3[11]; n# } nbin_buf_all = struct.pack(id11s, buf1, buf2, buf3) nret_all = struct.unpack(id11s, bin_buf_all) nprint bin_buf_all, <====> , ret_alln

輸出結果如下:

demo1輸出結果

詳解struct模塊

主要函數

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

# 按照給定的格式化字元串,把數據封裝成字元串(實際上是類似於c結構體的位元組流)string = struct.pack(fmt, v1, v2, ...)# 按照給定的格式(fmt)解析位元組流string,返回解析出來的

tupletuple = unpack(fmt, string)# 計算給定的格式(fmt)佔用多少位元組的內存offset = calcsize(fmt)

struct中的格式化字元串

struct中支持的格式如下表:

注1:q和Q只在機器支持64位操作時有意思

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

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

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

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

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

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

參考

[1] Python使用struct處理二進位(Python使用struct處理二進位 - Gala - 博客園)

原文鏈接:jianshu.com/p/5a985f29f

查閱更為簡潔方便的分類文章以及最新的課程、產品信息,請移步至全新呈現的www.leadai.org

推薦閱讀:

草根學Python(三)List 和 Tuple
優雅的 Python 之 Ellipsis
python編程基礎(二)
(做生物信息的)你們是怎麼知道Python裡面sys.argv和getopt這種函數的?
Python 多線程效率不高嗎?

TAG:Python |