Python二進位制資料結構Struct的具體使用

2022-09-25 10:48:12 字數 2792 閱讀 6329

目錄

在c/c++語言中,struct被稱為結構體。而在python中,struct是乙個專門的庫,用於處理位元組串與原生python資料結構型別之間的轉換。

本篇,將詳細介紹二進位制資料結構struct的使用方式。

struct庫包含了一組處理結構值得模組級函式,以及乙個struct類。格式指示符將由字串格式轉換為一種編譯表示,這與處理正規表示式得方式類似。

這個轉換會耗費一些資源,所以建立乙個struct例項並再這個例項上呼叫方法時,只完成一次轉換,往往會更高效。

struct支援使用格式指示符將資料打包為字串,另外支援從字串解包資料,格式指示符由表示資料型別的字串和可選的數量及位元組序指示符構成。

下面,我們來打包乙個元組,將其轉換為16進製制位元組序列,示例如下:

import struct

import binascii

values = (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))

執行之後,效果如下:

這裡的格式指示符為「i 3s f」。前面介紹array陣列時,我們已經列出過乙個**。其中i標識乙個整型或長整型,3s表示3個位元組字串(lyj),f表示浮點數。

struct庫使用unpack()可以從打包的表示資料中抽取資料,這裡直接複製上面的打包值,進行測試。示例如下:

import struct

import binascii

packed_data = binascii.unhexlify(b'020000006c796a0033337340')

s = struct.struct('i 3s f')

unpacked_data = s.unpack(packed_data)

print("解包值:", unpacked_data)

執行之後,效果如下:

雖然使用unpack()解包基本會得到相同值,但浮點數的值有微小的差別。

預設情況下,值會使用原生c庫的位元組序(endianness)來編碼。struct的位元組序指示符如下表所示:

**含義

@原生順序

=原生標準

<

小端iabtpoclu

>大端!

網路順序

示例如下:

import struct

import binascii

values = (2, 'lyj'.encode('utf-8'), 3www.cppcns.com.8)

endianness = [

('@', '原生順序'),

('=', '原生標準'),

('', '大端'),

('!', '網路順序'),

]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))

執行之後,效果如下:

如果想改變位元組序來編碼,如上面**所示,只需要改變格式串中提供乙個顯式的位元組序指令,就可以很容易地覆蓋這個預設選擇。

通常在強調效能的情況下或者向擴充套件模組傳入或傳出資料時才會處理二進位制打包資料。

為了避免為每個打包結構分配乙個新緩衝區所帶來的開銷,通常情況下,我們使用pack_into()和unpack_from()方法支援直接寫入預分配的緩衝區。

示例如下:

import struct

import binascii

import ctypes

import array

values = (2, 'lyj'.encode('utf-8'), 3.8)

s = struct.struct('i 3s f')

print("原始值:", values)

b = ctypes.create_string_buffer(s.size)

print("打包之前(緩衝區的值):", binascii.hexlify(b.raw))

s.pack_into(b, 0, *values)

print("打包之後(緩衝區的值):", bina程式設計客棧scii.hexlify(b.raw))

print("解包:", s.unpack_from(b, 0))

a = array.array('b', b'\0' * s.size)

print("打包之前(緩衝區的值):", binascii.hexlify(a))

s.pack_into(a, 0, *values)

print('打包之後(緩衝程式設計客棧區的值):', binascii.hexlify(aiabtpoclu))

print("解包:", s.unpack_from(a, 0))

執行之後,效果如下:

這裡通過兩種方式,建立緩衝區。其中size屬性用於指出緩衝區需要的大小。

資料結構 二進位制索引樹

1 2 解釋 binary indexed tree made easy hackerearth 3 應用 1 leetcode 求翻轉對 2 算數編輯器 先記思路之後整理 1 乙個整數可以用一組 2 的平方和表示 2 hamming weight is the number of 1 s in t...

二進位制 二進位制起源

現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...

二進位制資料

今天的問題是處理。本來想在資料庫中只存儲存路徑的,但是同組的同事說別那樣,還是直接存比較好,雖然不知道為什麼一定要存,但是或許他說的有道理吧,至於為什麼暫時還沒想通。處理二進位制遇到的第乙個問題是讀寫的問題,data open filepath,rb data open filepath,wb 作為...