日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python序列化模块struct_python的struct模块

發布時間:2025/3/15 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python序列化模块struct_python的struct模块 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python中缺少類似C語言structs這樣直接對字節序列進行序列化和反序列化的語法,作為一門腳本語言這是不必要的,但作為一門完整的編程語言必須提供這樣的能力,否則不能獨立的處理二進制文件和數據流。struct模塊即為處理這類問題而誕生。

要處理字節序需要三個能力:首先是字節和變量值的互相轉化,其次是字節序序問題,最后是數據對其的處理。

python中的基本變量類型有限,分別為int,float,bool類型。并且根據不同的運行環境所占用的長度不確定,這點跟C語言完全沒法比。因此模塊中我們需要提供一個確定變量和字節長度的轉換方法,也就是struct模塊中的 Format Characters。還有字節序的問題,Inter x86 和AMD64 系列主機都是小尾數,而網絡字節序是大尾數的字節序,并且有時我們要處理一份二進制文件事先并不知道其是大尾數還是小尾數表示,這些都需要開發人員去指定,因此需要提供對字節序的控制,在struct中也有對應的處理 Byte Order。 最后就是數據對其的處理,我們知道C語言中為了更有效的處理struct類型會進行對其處理,例如結構體 Student代碼如下,如果按照基本類型計算 一個char占用一個字節,兩個int共占用8個自己,應該是9個字節的長度,但實際占用了12個字節。C編譯器在處理如下結構體時一般按4字節對齊,這樣在gender和class_id之間會有3個字節用于對齊。

struct Student{

char gender;

int class_id;

int age;

};

int main(int argc, const char * argv[]) {

// insert code here...

printf("length of int %ld\n",sizeof(int));

printf("length of Student %ld\n",sizeof(Student));

return 0;

}

>> output

length of int 4

length of Student 12

struct 模塊中將對其與字節序控制結合在一起,通過結構化字符串的首字符控制,如下:

字符

字節序

是否sizeof對其

@

本機

=

本機

>

小尾數

<

大尾數

!

網絡字節序(大尾數)

@ 是默認字符,如果結構化字符串沒有字節序控制符則默認為@。

接下來看變量和字節轉換控制符有哪些:

符號

C 類型

Python 類型

字節長度

x

對其位

-

-

c

char

長度為1的 bytes 字符串

1

b

signed char

int

1

B

unsigned char

int

1

?

_Bool

bool

1

h

short

int

2

H

unsigned short

int

2

i

int

int

4

I

unsigned int

int

4

l

long

int

4

L

unsigned long

int

4

q

long long

int

4

Q

unsigned long long

int

4

n

ssize_t

int

-

N

size_t

int

-

e

半精度浮點數(c不支持)

float

2

f

float

float

4

d

double

float

8

s

char[]

bytes

-

p

char[]

bytes

-

P

void *

bytes

-

struct通過格式化字符串將字節和變量互轉,格式化字符串由上述的字節序字符+格式化字符組成,且字節序字符可省略。例如: >hhl 表示兩個short 和一個long。

>>> from struct import *

>>> pack('>hhl', 1, 2, 3)

b'\x00\x01\x00\x02\x00\x00\x00\x03'

>>> unpack('>hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')

(1, 2, 3)

連續的格式化字符可以通過數字簡寫,>hhl完全等價與 >2hl。

上例中pack和unpack是struct模塊中的兩個方法,分別表示將變量值轉換為二進制字符串和從二進制字符串中轉換出變量值。在struct模塊中有4個基本的轉換函數、一個批量轉換的迭代器方法和一個計算長度的函數:

struct.pack(format, v1, v2, ...) # 打包

struct.pack_into(format, buffer, offset, v1, v2, ...)

struct.unpack(format, buffer) # 解碼

struct.unpack_from(format, buffer, offset=0)

如上4個基本轉換函數,其中pack和unpack是一對,pack將v1,v2的值按照format的格式轉化為二進制字符串,unpack將二進制字符串buffer按照format的格式轉換一元組。pack_into和unpack_into是一對,pack_into將v1,v2的值轉換成的二進制依次放入buffer中offset開始的位置。unpack_into則從buffer的offset開始轉換出變量值。

struct.calcsize(format)

calcsize方法類似于C語言中sizeof(Struct) 用于計算format具體占用多少字符。

struct.iter_unpack(format, buffer)

iter_unpack以迭代方式轉換buffer中的字節,每次都會讀取并轉化calcsize(format)長度的字節。

以上都是對struct模塊中功能的介紹,為了更清楚的看怎么使用,還是需要例子。

1、使用基礎的pack/unpack打包三個int型變量

>>> from struct import *

>>> pack('>hhl', 1, 2, 3)

b'\x00\x01\x00\x02\x00\x00\x00\x03'

>>> unpack('>hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')

(1, 2, 3)

>>> calcsize('hhl')

8

上述代碼與官網代碼中format字符串不同,加了個>符號,因為在mac操作系統python 2.7 的環境中c編譯的long占用8個字節因此l長度為8。整個結果并按住8位對其,pack結果為:'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'。

2、unpack 的結果可以直接通過變量接受,也可以使用命名元組。

>>> record = b'raymond \x32\x12\x08\x01\x08'

>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple

>>> Student = namedtuple('Student', 'name serialnum school gradelevel')

>>> Student._make(unpack('<10sHHb', record))

Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)

3、由于對其的原因,格式化字符的位置可能影響結構化的長度。

>>> pack('ci', b'*', 0x12131415)

b'*\x00\x00\x00\x12\x13\x14\x15'

>>> pack('ic', 0x12131415, b'*')

b'\x12\x13\x14\x15*'

>>> calcsize('ci')

8

>>> calcsize('ic')

5

struct 模塊不會對末尾的字符對其,如上c表示一個字節,在C語言中一個結構體不論先寫int還是char最終長度都為8,但是struct模塊中不同。如果想要結尾的字符也對其,需要用接下來的方法。

4、結尾使用 0 + 格式化字符的方式來結尾對其

>>> pack('llh', 1, 2, 3)

b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'

>>> pack('llh0l', 1, 2, 3)

b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

格式字符串llh最后的h占用2位,而格式字符串llh0l共占用12位

5、數字 + c和數字 + s的區別

>>> scbytes = b'abcde'

>>> unpack('5s',scbytes)

(b'abcde',)

>>> unpack('5c',scbytes)

(b'a', b'b', b'c', b'd', b'e')

>>>

可見 數字+c的方式解碼出5個長度為1的字符串,而數字+s的方式解碼出長度為5的一個字符串

除了直接使用函數的方式打包和解碼,struct模塊也支持使用類的方式。類定義如下:

class struct.Struct(format)

pack(v1, v2, ...)

pack_into(buffer, offset, v1, v2, ...)

unpack(buffer)

unpack_from(buffer, offset=0)

iter_unpack(buffer)

format

size

類定義包含五個方法和兩個屬性,其中五個方法與模塊中的方法一致。而size屬性則是calcsize方法的體現。

>>> record=b'raymond \x32\x12\x08\x01\x08'

>>> ray = Struct('<10sHHb')

>>> ray.unpack(record)

(b'raymond ', 4658, 264, 8)

>>> ray.pack(b'raymond ', 4658, 264, 8)

b'raymond 2\x12\x08\x01\x08'

總結

以上是生活随笔為你收集整理的python序列化模块struct_python的struct模块的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。