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
輸出結果如下:
詳解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 - 博客園)
原文鏈接:http://www.jianshu.com/p/5a985f29fa81
查閱更為簡潔方便的分類文章以及最新的課程、產品信息,請移步至全新呈現的www.leadai.org
推薦閱讀:
※草根學Python(三)List 和 Tuple
※優雅的 Python 之 Ellipsis
※python編程基礎(二)
※(做生物信息的)你們是怎麼知道Python裡面sys.argv和getopt這種函數的?
※Python 多線程效率不高嗎?
TAG:Python |