struct --- 將位元組直譯為打包起來的二進位資料¶
原始碼:Lib/struct.py
此模組可在 Python 數值與以 Python bytes 物件表示的 C 結構之間進行轉換。簡潔的格式字串描述了與 Python 數值之間預期的轉換。此模組的函式和物件可用於兩種截然不同的應用程式:與外部來源(檔案或網路連線)的資料交換,或是 Python 應用程式與 C 層之間的資料傳輸。
備註
當未給定前綴字元時會預設為原生模式。它會根據建構 Python 直譯器的平台和編譯器來打包或解包資料。打包給定 C 結構的結果包含填充位元組,以維持相關 C 型別的正確對齊;同樣地,解包時也會考量對齊。相反地,當在外部來源之間傳輸資料時,程式設計師需負責定義位元組順序和元素之間的填充。詳情請參見 位元組順序、大小和對齊。
一些 struct 函式(和 Struct 的方法)接受一個 buffer 引數。這是指實作緩衝協定 (Buffer Protocol) 並提供可讀或可讀寫緩衝區的物件。最常用於此目的的型別是 bytes 和 bytearray,但許多其他可以視為位元組陣列的型別都實作了緩衝區協定,因此它們可以從 bytes 物件讀取或填入資料而無需額外的複製。
函式與例外¶
此模組定義了以下例外和函式:
- exception struct.error¶
在各種情況下都可能觸發的例外;引數是一個描述錯誤內容的字串。
- struct.pack(format, v1, v2, ...)¶
回傳一個包含依照格式字串 format 打包的數值 v1、v2、... 的位元組物件。引數必須完全符合格式所需的數值。
- struct.pack_into(format, buffer, offset, v1, v2, ...)¶
依照格式字串 format 打包數值 v1、v2、...,並將打包後的位元組寫入可寫緩衝區 buffer 中從位置 offset 開始的地方。請注意 offset 是必要的引數。
- struct.unpack(format, buffer)¶
根據格式字串 format 從緩衝區 buffer(推測是由
pack(format, ...)打包的)解包。結果是一個元組,即使它只包含一個項目。緩衝區的位元組大小必須符合格式所需的大小,如calcsize()所示。
- struct.unpack_from(format, /, buffer, offset=0)¶
根據格式字串 format 從 buffer 的 offset 位置開始解包。即使它只包含一個項目,結果也都是一個元組。緩衝區從位置 offset 開始的位元組大小,必須至少達到格式所需的大小,如
calcsize()所示。
- struct.iter_unpack(format, buffer)¶
根據格式字串 format 疊代地從緩衝區 buffer 解包。此函式回傳一個疊代器,它會從緩衝區讀取等大小的區塊,直到消耗完所有內容。緩衝區的位元組大小必須是格式所需大小的倍數,如
calcsize()所示。每次疊代都會產生 (yield) 出一個由格式字串指定的元組。
在 3.4 版被加入.
- struct.calcsize(format)¶
回傳對應於格式字串 format 的結構大小(因此也是
pack(format, ...)所產生的位元組物件的大小)。
格式字串¶
格式字串描述了打包和解包資料時的資料配置 (layout)。它們由格式字元組成,這些字元指定了要打包或解包的資料型別。此外,特殊字元控制位元組順序、大小和對齊。每個格式字串由一個可選的前綴字元組成,描述資料的整體屬性,以及一個或多個描述實際資料值和填充的格式字元。
位元組順序、大小和對齊¶
預設情況下,C 型別以機器的原生格式和位元組順序表示,並在必要時透過跳過填充位元組來正確對齊(根據 C 編譯器所使用的規則)。選擇此行為使得打包結構的位元組完全對應於相對應 C 結構的記憶體配置。是否使用原生位元組順序和填充或標準格式取決於應用程式。
或者,格式字串的第一個字元可以用來指示打包資料的位元組順序、大小和對齊,如下表所示:
字元 |
位元組順序 |
大小 |
對齊 |
|---|---|---|---|
|
原生 |
原生 |
原生 |
|
原生 |
標準 |
無 |
|
小端序 |
標準 |
無 |
|
大端序 |
標準 |
無 |
|
網路(= 大端序) |
標準 |
無 |
如果第一個字元不是這些字元之一,則假設為 '@'。
備註
數字 1023(十六進位為 0x3ff)具有以下位元組表示法:
大端序(
>)為03 ff小端序(
<)為ff 03
Python 範例:
>>> import struct
>>> struct.pack('>h', 1023)
b'\x03\xff'
>>> struct.pack('<h', 1023)
b'\xff\x03'
原生位元組順序是大端序或小端序,會取決於主機系統。例如,Intel x86、AMD64 (x86-64)和 Apple M1 是小端序;IBM z 和許多舊架構是大端序。可使用 sys.byteorder 來檢查你系統的位元組順序。
原生大小和對齊是使用 C 編譯器的 sizeof 運算式來決定的。這總是與原生位元組順序結合使用。
標準大小僅取決於格式字元;請參見格式字元區塊中的表格。
請注意 '@' 和 '=' 之間的差異:兩者都使用原生位元組順序,但後者的大小和對齊是標準化的。
'!' 形式表示網路位元組順序,根據 IETF RFC 1700 的定義,它總是大端序。
沒有方法來指示非原生位元組順序(強制位元組交換);請使用適當的 '<' 或 '>' 選擇。
註解:
填充只會在連續的結構成員之間自動加入。編碼結構的開頭或結尾不會加入填充。
使用非原生大小和對齊時,例如使用 '<'、'>'、'=' 和 '!' 時,不會加入填充。
要將結構的結尾對齊到特定型別的對齊需求,請以該型別的碼結束格式,重複次數為零。請參見範例。
格式字元¶
格式字元具有以下意義;在給定型別的情況下,C 和 Python 數值之間的轉換應該是顯而易見的。「標準大小」欄位指的是使用標準大小時(即當格式字串以 '<'、'>'、'!' 或 '=' 其中之一開始時)打包數值的位元組大小。使用原生大小時,打包數值的大小取決於平台。
格式 |
C Type |
Python 型別 |
標準大小 |
註解 |
|---|---|---|---|---|
|
填充位元組 |
無值 |
(7) |
|
|
char |
長度為 1 的位元組 |
1 |
|
|
signed char |
整數 |
1 |
(1), (2) |
|
unsigned char |
整數 |
1 |
(2) |
|
_Bool |
bool |
1 |
(1) |
|
short |
整數 |
2 |
(2) |
|
unsigned short |
整數 |
2 |
(2) |
|
int |
整數 |
4 |
(2) |
|
unsigned int |
整數 |
4 |
(2) |
|
long |
整數 |
4 |
(2) |
|
unsigned long |
整數 |
4 |
(2) |
|
long long |
整數 |
8 |
(2) |
|
unsigned long long |
整數 |
8 |
(2) |
|
|
整數 |
(3) |
|
|
|
整數 |
(3) |
|
|
_Float16 |
float |
2 |
(4), (6) |
|
float |
float |
4 |
(4) |
|
double |
float |
8 |
(4) |
|
float complex |
complex |
8 |
(10) |
|
double complex |
complex |
16 |
(10) |
|
char[] |
位元組 |
(9) |
|
|
char[] |
位元組 |
(8) |
|