天天看點

python 中pack和unpack的用法

Python是一門非常簡潔的語言,對于資料類型的表示,不像其他語言預定義了許多類型(如:在C#中,光整型就定義了8種),它隻定義了六種基本類型:字元串,整數,浮點數,元組,清單,字典。通過這六種資料類型,我們可以完成大部分工作。但當Python需要通過網絡與其他的平台進行互動的時候,必須考慮到将這些資料類型與其他平台或語言之間的類型進行互相轉換問題。打個比方:C++寫的用戶端發送一個int型(4位元組)變量的資料到Python寫的伺服器,Python接收到表示這個整數的4個位元組資料,怎麼解析成Python認識的整數呢? Python的标準子產品struct就用來解決這個問題。

struct子產品的内容不多,也不是太難,下面對其中最常用的方法進行介紹:

struct.pack

struct.pack用于将Python的值根據格式符,轉換為字元串(因為Python中沒有位元組(Byte)類型,可以把這裡的字元串了解為位元組流,或位元組數組)。其函數原型為:struct.pack(fmt, v1, v2, ...),參數fmt是格式字元串,關于格式字元串的相關資訊在下面有所介紹。v1, v2, ...表示要轉換的python值。下面的例子将兩個整數轉換為字元串(位元組流):

import struct   

a = 20  

b = 400  

str = struct.pack("ii", a, b)  #轉換後的str雖然是字元串類型,但相當于其他語言中的位元組流(位元組數組),可以在網絡上傳輸   

print 'length:', len(str)   

print str   

print repr(str)   

#---- result   

#length: 8   

#    ----這裡是亂碼   

#'/x14/x00/x00/x00/x90/x01/x00/x00'  

格式符"i"表示轉換為int,'ii'表示有兩個int變量。進行轉換後的結果長度為8個位元組(int類型占用4個位元組,兩個int為8個位元組),可以看到輸出的結果是亂碼,因為結果是二進制資料,是以顯示為亂碼。可以使用python的内置函數repr來擷取可識别的字元串,其中十六進制的0x00000014, 0x00001009分别表示20和400。

struct.unpack

struct.unpack做的工作剛好與struct.pack相反,用于将位元組流轉換成python資料類型。它的函數原型為:struct.unpack(fmt, string),該函數傳回一個元組。 下面是一個簡單的例子:str = struct.pack("ii", 20, 400)   

a1, a2 = struct.unpack("ii", str)   

print 'a1:', a1   

print 'a2:', a2   

#---- result:   

#a1: 20   

#a2: 400  

struct.calcsize

struct.calcsize用于計算格式字元串所對應的結果的長度,如:struct.calcsize('ii'),傳回8。因為兩個int類型所占用的長度是8個位元組。

struct.pack_into, struct.unpack_from

這兩個函數在Python手冊中有所介紹,但沒有給出如何使用的例子。其實它們在實際應用中用的并不多。Google了很久,才找到一個例子,貼出來共享一下:

import struct   

from ctypes import create_string_buffer   

buf = create_string_buffer(12)   

print repr(buf.raw)   

struct.pack_into("iii", buf, 0, 1, 2, -1)   

print repr(buf.raw)   

print struct.unpack_from('iii', buf, 0)   

#---- result   

#'/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00'   

#'/x01/x00/x00/x00/x02/x00/x00/x00/xff/xff/xff/xff'   

#(1, 2, -1)