python學習筆記7.5-內建模組struct
阿新 • • 發佈:2019-02-02
Python中變數的型別只有列表、元祖、字典、集合等高階抽象型別,並沒有像c中定義了位、位元組、整型等底層初級型別。因為Python本來就是高階解釋性語言,執行的時候都是經過翻譯後再在底層執行。如何打通Python和其他語言之間的型別定義障礙,Python的內建模組struct完全解決了所有問題。
知識介紹:
在struct模組中最最常用的三個:
(1)struct.pack:用於將Python的值根據格式符,轉換為字串(因為Python中沒有位元組(Byte)型別,可以把這裡的字串理解為位元組流,或位元組陣列)。
(2)struct.unpack: 剛好與struct.pack相反,用於將位元組流轉換成python資料型別,該函式返回一個元組。
(3)struct.calcsize: 計算格式字串所對應的結果的長度。
轉換過程中遇到的格式操作:
格式符 | C語言型別 | Python型別 |
---|---|---|
x | pad byte | no value |
c | char | string of length 1 |
b | signed char | integer |
B | unsigned char | integer |
? | _Bool | bool |
h | short | integer |
H | unsigned short | integer |
i | int | integer |
I | unsigned int | integer or long |
l | long | integer |
L | unsigned long | long |
q | long long | long |
Q | unsigned long long | long |
f | float | float |
d | double | float |
s | char[] | string |
p | char[] | string |
P | void * | long |
例項詳解:
#!/usr/bin/python
# -*- coding:utf-8 -*-
'''測試struct模組'''
from struct import *
import array
def fun_calcsize():
print 'ci:',calcsize('ci')#計算格式佔記憶體大小
print '@ci:',calcsize('@ci')
print '=ci:',calcsize('=ci')
print '>ci:',calcsize('>ci')
print '<ci:',calcsize('<ci')
print 'ic:',calcsize('ic')#計算格式佔記憶體大小
print '@ic:',calcsize('@ic')
print '=ic:',calcsize('=ic')
print '>ic:',calcsize('>ic')
print '<ic:',calcsize('<ic')
def fun_pack(Format,msg = [0x11223344,0x55667788]):
result = pack(Format,*msg)
print 'pack'.ljust(10),str(type(result)).ljust(20),
for i in result:
print hex(ord(i)), # ord把ASCII碼錶中的字元轉換成對應的整形,hex將數值轉化為十六進位制
print
result = unpack(Format,result)
print 'unpack'.ljust(10),str(type(result)).ljust(20),
for i in result:
print hex(i),
print
def fun_pack_into(Format,msg = [0x11223344,0x55667788]):
r = array.array('c',' '*8)#大小為8的可變緩衝區,writable buffer
result = pack_into(Format,r,0,*msg)
print 'pack_into'.ljust(10),str(type(result)).ljust(20),
for i in r.tostring():
print hex(ord(i)),
print
result = unpack_from(Format,r,0)
print 'pack_from'.ljust(10),str(type(result)).ljust(20),
for i in result:
print hex(i),
print
def IsBig_Endian():
'''判斷本機為大/小端'''
a = 0x12345678
result = pack('i',a)#此時result就是一個string字串,字串按位元組同a的二進位制儲存內容相同。
if hex(ord(result[0])) == '0x78':
print '本機為小端'
else:
print '本機為大端'
def test():
a = '1234'
for i in a:
print '字元%s的二進位制:'%i,hex(ord(i))#字元對應ascii碼錶中對應整數的十六進位制
'''
不用unpack()返回的資料也是可以使用pack()函式的,只要解包的字串符合解包格式即可,
pack()會按照解包格式將字串在記憶體中的二進位制重新解釋(說的感覺不太好...,見下例)
'''
print '大端:',hex(unpack('>i',a)[0])#因為pack返回的是元組,即使只有一個元素也是元組的形式
print '小端:',hex(unpack('<i',a)[0])
if __name__ == "__main__":
print '判斷本機是否為大小端?',
IsBig_Endian()
fun_calcsize()
print '大端:'
Format = ">ii"
fun_pack(Format)
fun_pack_into(Format)
print '小端:'
Format = "<ii"
fun_pack(Format)
fun_pack_into(Format)
print 'test'
test()
'''
result:
判斷本機是否為大小端? 本機為小端
ci: 8
@ci: 8
=ci: 5
>ci: 5
<ci: 5
ic: 5
@ic: 5
=ic: 5
>ic: 5
<ic: 5
大端:
pack <type 'str'> 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
unpack <type 'tuple'> 0x11223344 0x55667788
pack_into <type 'NoneType'> 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
pack_from <type 'tuple'> 0x11223344 0x55667788
小端:
pack <type 'str'> 0x44 0x33 0x22 0x11 0x88 0x77 0x66 0x55
unpack <type 'tuple'> 0x11223344 0x55667788
pack_into <type 'NoneType'> 0x44 0x33 0x22 0x11 0x88 0x77 0x66 0x55
pack_from <type 'tuple'> 0x11223344 0x55667788
test
字元1的二進位制: 0x31
字元2的二進位制: 0x32
字元3的二進位制: 0x33
字元4的二進位制: 0x34
大端:0x31323334
小端:0x34333231
'''