🍖struct 模塊的簡單使用

詳細使用參考官方文檔 : https://docs.python.org/zh-cn/2/library/struct.htmlhtml

struct 簡單介紹

structPython 的內置模塊, 在使用 socket 通訊的時候, 大多數據的傳輸都是以二進制流的形式的存在, 而 struct 模塊就提供了一種機制, 該機制能夠將某些特定的結構體類型打包成二進制流的字符串而後再網絡傳輸,而接收端也應該能夠經過某種機制進行解包還原出原始的結構體數據python

struct 的使用

struct 模塊能夠將任意大小的數字轉換成一個固定長度(可選擇)的 bytes, 這個原理相似於前面章節講過的 hash 算法, 不論內容多大, 最終的 hash 值長度不變, 不一樣的是 hash 算法是不可逆的, 並且傳入的原材料能夠是文本、字符串等許多數據類型, struct 能夠反解出原來的數字算法

ps : struct 模塊只能轉換數字, 不能轉換其餘的數據類型json

基本使用 pack 和 unpack

  • 🔹正確使用示例
import struct

res = struct.pack("i",1234566)  # 傳入的必須是 int 類型
print(res)          # b'\x86\xd6\x12\x00'  (是個二進制)
print(type(res))    # <class 'bytes'>      (查看類型)

res2 = struct.unpack("i",res)   # 使用什麼 Format 打包就用什麼解包
print(res2)         # (1234566,)           (是個元組)
print(type(res2))   # <class 'tuple'>      (查看類型)
print(res2[0])      # 1234566
  • 🔸傳入非 int 類型引起的錯誤示例
import struct

res = struct.pack("i","1231")
# 拋出異常 : struct.error: required argument is not an integer (參數必須是整數)
  • 🔸解包時使用的 Format 不一致錯誤示例
import struct

res = struct.pack("i",123)

res2 = struct.unpack("q",res)
# struct.error: unpack requires a buffer of 8 bytes
  • 🔹傳入多個值
res = struct.pack("hiq",12,23,451312)  # 傳入多個值, 並使用不一樣的 Fromat
print(res)  # b'\x0c\x00\x00\x00\x17\x00\x00\x00\xf0\xe2\x06\x00\x00\x00\x00\x00'
print(type(res))  # <class 'bytes'>

a,b,c = struct.unpack("hiq",res)  # 使用解壓賦值,有幾個值就須要有幾個 Fromat
print(a,b,c)                      # 12 23 451312
  • 🔸Fromat 與值不一致錯誤示例
with open("aaa.txt","wb")as f:
    for i in range(5):
        res = struct.pack("i",i)
        f.write(res)
        
with open("aaa.txt","rb")as f:
    res = f.read()
    print(res)
    a,b,c,d,e= struct.unpack("i",res)  # 打包的時候是 5 個值, 解包的時候也要傳 5 個值
    print(a,b,c,d,e)  # 拋出異常 : struct.error: unpack requires a buffer of 4 bytes
  • 🔹打包一個 json 後的信息長度, 在 socket 中可用於發送報頭(報頭爲固定長度)
import struct
import json

dic = {
    "header_name" : "a.txt",
    "total_size" : 22,
    "heash" : "shawn"
}

res = json.dumps(dic)  # 將報頭序列化
lens = struct.pack("i",len(res))  # 將報頭的長度傳入並打包
lens2 = struct.unpack("i",lens)   # 假設通訊另外一端收到打包的二進制,再進行解包拿到長度
print(lens2)    # (60,)
print(lens[0])  # 60

打包字節長度對照表

字符(Format) cType Python type Standard size
x pad byte no value
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I(大寫i) unsigned int integer 4
l(小寫L) long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
f float float 4
d double float 8
s charl string
p charl string
P void* integer
相關文章
相關標籤/搜索