Python之struct模块的使用

struct模块的作用

    可以完成字节与原生Python数据类型(如数字和字符串)之间的转换

struct提供了一组处理结构值的模块级函数,另外还有一个Struct类。格式指示符将由字符串格式转换为一种编译表示,这与处理正则表达式的方式类似。
这个转换会耗费一些资源,所以创建一个Struct实例并在这个实例上调用方法时(不是使用模块级函数)只完成一次转换,这会更高效。

1、用struct.pack封包

import struct
import binascii

values = (1, 'ab'.encode('utf-8'), 2.7)

s = struct.Struct('I 2s f')
packed_data = s.pack(*values)

print('Original values:', values)  # 源始数据
print('Format string  :', s.format)  # 输出数据格式
print('Uses           :', s.size, 'bytes')  # 打印字节大小
print('Packed Value   :', binascii.hexlify(packed_data))  # 将数据转为十六进制显示
struct_pack.py

运行效果

Original values: (1, b'ab', 2.7)
Format string  : I 2s f
Uses           : 12 bytes
Packed Value   : b'0100000061620000cdcc2c40'

2、用struct.pack解包

import struct
import binascii

packed_data = binascii.unhexlify(b'0100000061620000cdcc2c40')

s = struct.Struct('I 2s f')
unpacked_data = s.unpack(packed_data)
print('Unpacked Values:', unpacked_data)
struct_unpack.py

运行效果

Unpacked Values: (1, b'ab', 2.700000047683716)

3、以上封包与解包字节十六进制字节序列的总结

binascii.hexlify() #转变十六进制的字节序列
binascii.unhexlify()#将十六进制字节序列,转为字节

4、字节序的排序

import struct
import binascii

values = (1, 'ab'.encode('utf-8'), 2.7)
print('Original values:', values)

endianness = [
    ('@', 'native, native'),
    ('=', 'native, standard'),
    ('<', 'little-endian'),
    ('>', 'big-endian'),
    ('!', 'network'),
]

for code, name in endianness:
    s = struct.Struct(code + ' I 2s f')
    packed_data = s.pack(*values)
    print('=====>', code, name)
    print('Format string  :', s.format, 'for', name)
    print('Uses           :', s.size, 'bytes')
    print('Packed Value   :', binascii.hexlify(packed_data))
    print('Unpacked Value :', s.unpack(packed_data))
struct_endianness.py

运行效果

Original values: (1, b'ab', 2.7)
=====> @ native, native
Format string  : @ I 2s f for native, native
Uses           : 12 bytes
Packed Value   : b'0100000061620000cdcc2c40'
Unpacked Value : (1, b'ab', 2.700000047683716)

=====> = native, standard
Format string  : = I 2s f for native, standard
Uses           : 10 bytes
Packed Value   : b'010000006162cdcc2c40'
Unpacked Value : (1, b'ab', 2.700000047683716)

=====> < little-endian
Format string  : < I 2s f for little-endian
Uses           : 10 bytes
Packed Value   : b'010000006162cdcc2c40'
Unpacked Value : (1, b'ab', 2.700000047683716)

=====> > big-endian
Format string  : > I 2s f for big-endian
Uses           : 10 bytes
Packed Value   : b'000000016162402ccccd'
Unpacked Value : (1, b'ab', 2.700000047683716)

=====> ! network
Format string  : ! I 2s f for network
Uses           : 10 bytes
Packed Value   : b'000000016162402ccccd'
Unpacked Value : (1, b'ab', 2.700000047683716)

Struct的字节序指示符

代码含义
@ 原生顺序
= 原生标准 
< 小端
> 大端
! 网络顺序

 

 

 

 

 

 

 

5、缓冲区的使用

import array
import binascii
import ctypes
import struct

s = struct.Struct('I 2s f')
values = (1, 'ab'.encode('utf-8'), 2.7)
print('Original:', values)

print()
print('ctypes string buffer')

b = ctypes.create_string_buffer(s.size)  # 创建ctype字符串缓冲区
print(b)
print('Before  :', binascii.hexlify(b.raw))
s.pack_into(b, 0, *values)
print('After   :', binascii.hexlify(b.raw))
print('Unpacked:', s.unpack_from(b, 0))

print()
print('array')

a = array.array('b', b'\0' * s.size)
print('Before  :', binascii.hexlify(a))
s.pack_into(a, 0, *values)
print('After   :', binascii.hexlify(a))
print('Unpacked:', s.unpack_from(a, 0))
struct_buffers.py

 

运行效果

Original: (1, b'ab', 2.7)

ctypes string buffer
<ctypes.c_char_Array_12 object at 0x000001D61B42F448>
Before  : b'000000000000000000000000'
After   : b'0100000061620000cdcc2c40'
Unpacked: (1, b'ab', 2.700000047683716)

array
Before  : b'000000000000000000000000'
After   : b'0100000061620000cdcc2c40'
Unpacked: (1, b'ab', 2.700000047683716)
posted @ 2020-06-28 10:48  小粉优化大师  阅读(298)  评论(0编辑  收藏  举报