Python二進(jìn)制數(shù)據(jù)結(jié)構(gòu)Struct的具體使用
在C/C++語(yǔ)言中,struct被稱為結(jié)構(gòu)體。而在Python中,struct是一個(gè)專門(mén)的庫(kù),用于處理字節(jié)串與原生Python數(shù)據(jù)結(jié)構(gòu)類型之間的轉(zhuǎn)換。
本篇,將詳細(xì)介紹二進(jìn)制數(shù)據(jù)結(jié)構(gòu)struct的使用方式。
函數(shù)與Struct類struct庫(kù)包含了一組處理結(jié)構(gòu)值得模塊級(jí)函數(shù),以及一個(gè)Struct類。格式指示符將由字符串格式轉(zhuǎn)換為一種編譯表示,這與處理正則表達(dá)式得方式類似。
這個(gè)轉(zhuǎn)換會(huì)耗費(fèi)一些資源,所以創(chuàng)建一個(gè)Struct實(shí)例并再這個(gè)實(shí)例上調(diào)用方法時(shí),只完成一次轉(zhuǎn)換,往往會(huì)更高效。
打包Struct支持使用格式指示符將數(shù)據(jù)打包為字符串,另外支持從字符串解包數(shù)據(jù),格式指示符由表示數(shù)據(jù)類型的字符串和可選的數(shù)量及字節(jié)序指示符構(gòu)成。
下面,我們來(lái)打包一個(gè)元組,將其轉(zhuǎn)換為16進(jìn)制字節(jié)序列,示例如下:
import structimport binasciivalues = (2, ’lyj’.encode(’UTF-8’), 3.8)s = struct.Struct(’I 3s f’)packed_data = s.pack(*values)print('原值:', values)print('格式指示符:', s.format)print('大小:', s.size, ’bytes’)print('打包值:', binascii.hexlify(packed_data))
運(yùn)行之后,效果如下:
這里的格式指示符為“I 3s f”。前面介紹array數(shù)組時(shí),我們已經(jīng)列出過(guò)一個(gè)表格。其中I標(biāo)識(shí)一個(gè)整型或長(zhǎng)整型,3s表示3個(gè)字節(jié)字符串(lyj),f表示浮點(diǎn)數(shù)。
解包struct庫(kù)使用unpack()可以從打包的表示數(shù)據(jù)中抽取數(shù)據(jù),這里直接復(fù)制上面的打包值,進(jìn)行測(cè)試。示例如下:
import structimport binasciipacked_data = binascii.unhexlify(b’020000006c796a0033337340’)s = struct.Struct(’I 3s f’)unpacked_data = s.unpack(packed_data)print('解包值:', unpacked_data)
運(yùn)行之后,效果如下:
雖然使用unpack()解包基本會(huì)得到相同值,但浮點(diǎn)數(shù)的值有微小的差別。
字節(jié)序指示符默認(rèn)情況下,值會(huì)使用原生C庫(kù)的字節(jié)序(endianness)來(lái)編碼。Struct的字節(jié)序指示符如下表所示:
代碼 含義 @ 原生順序 = 原生標(biāo)準(zhǔn) < 小端 > 大端 ! 網(wǎng)絡(luò)順序
示例如下:
import structimport binasciivalues = (2, ’lyj’.encode(’UTF-8’), 3.8)endianness = [ (’@’, ’原生順序’), (’=’, ’原生標(biāo)準(zhǔn)’), (’<’, ’小端’), (’>’, ’大端’), (’!’, ’網(wǎng)絡(luò)順序’),]for code, name in endianness: s = struct.Struct(code + ’ I 3s f’) packed_data = s.pack(*values) print('格式化字符串:', s.format, ’ for ’, name) print('大小:', s.size, ’bytes’) print('打包:', binascii.hexlify(packed_data)) print('解包:', s.unpack(packed_data))
運(yùn)行之后,效果如下:
如果想改變字節(jié)序來(lái)編碼,如上面代碼所示,只需要改變格式串中提供一個(gè)顯式的字節(jié)序指令,就可以很容易地覆蓋這個(gè)默認(rèn)選擇。
緩沖區(qū)通常在強(qiáng)調(diào)性能的情況下或者向擴(kuò)展模塊傳入或傳出數(shù)據(jù)時(shí)才會(huì)處理二進(jìn)制打包數(shù)據(jù)。
為了避免為每個(gè)打包結(jié)構(gòu)分配一個(gè)新緩沖區(qū)所帶來(lái)的開(kāi)銷(xiāo),通常情況下,我們使用pack_into()和unpack_from()方法支持直接寫(xiě)入預(yù)分配的緩沖區(qū)。
示例如下:
import structimport binasciiimport ctypesimport arrayvalues = (2, ’lyj’.encode(’UTF-8’), 3.8)s = struct.Struct(’I 3s f’)print('原始值:', values)b = ctypes.create_string_buffer(s.size)print('打包之前(緩沖區(qū)的值):', binascii.hexlify(b.raw))s.pack_into(b, 0, *values)print('打包之后(緩沖區(qū)的值):', binascii.hexlify(b.raw))print('解包:', s.unpack_from(b, 0))a = array.array(’b’, b’0’ * s.size)print('打包之前(緩沖區(qū)的值):', binascii.hexlify(a))s.pack_into(a, 0, *values)print(’打包之后(緩沖區(qū)的值):’, binascii.hexlify(a))print('解包:', s.unpack_from(a, 0))
運(yùn)行之后,效果如下:
這里通過(guò)兩種方式,創(chuàng)建緩沖區(qū)。其中size屬性用于指出緩沖區(qū)需要的大小。
到此這篇關(guān)于Pytho 二進(jìn)制數(shù)據(jù)結(jié)構(gòu)Struct的具體使用的文章就介紹到這了,更多相關(guān)Pytho 二進(jìn)制數(shù)據(jù)結(jié)構(gòu)Struct內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. JAMon(Java Application Monitor)備忘記2. 如何清空python的變量3. Python 如何展開(kāi)嵌套的序列4. 在JSP中使用formatNumber控制要顯示的小數(shù)位數(shù)方法5. Spring security 自定義過(guò)濾器實(shí)現(xiàn)Json參數(shù)傳遞并兼容表單參數(shù)(實(shí)例代碼)6. Java類加載機(jī)制實(shí)現(xiàn)步驟解析7. Python TestSuite生成測(cè)試報(bào)告過(guò)程解析8. Python os庫(kù)常用操作代碼匯總9. Python OpenCV去除字母后面的雜線操作10. 增大python字體的方法步驟
