Python模块学习:struct模块

python strtuct模块主要在Python中的值于C语言结构之间的转换。可用于处理存储在文件或网络连接(或其它来源)中的二进制数据。

import struct

'''
数据格式
名字  职业   年
muyu  coder 2018
'''

name = b'muyu'
job = b'coder'
year = 2018


file = open(r'test.bin', 'wb+')
file.write(struct.pack('4s5si', name, job, year))
file.flush()

file.seek(0)
strBin = file.read()
print(strBin) # b'muyucoder\x00\x00\x00\xe2\x07\x00\x00'

content = struct.unpack('4s5si', strBin)
print(content) # (b'muyu', b'coder', 2018)

,以二进制格式打开一个文件,以指定格式写入一个二进制串,再从文件取出二进制串,再把取出的串翻译成python数据

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)) 
#使用函数 binascii.hexlify() 将打包值转换为十六进制字节序列以进行打印。

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

struct 最常用的方法有两个:

  • struct.pack(fmt,v1,v2,…)
    返回的是一个字符串,是参数按照fmt数据格式组合而成
  • struct.unpack(fmt,string)
    按照给定数据格式解开(通常都是由struct.pack进行打包)数据,返回值是一个tuple

两个方法的第一个参数都是fmt
在这里插入图片描述
字节顺序
另一方面,打包的后的字节顺序默认上是由操作系统的决定的,当然struct模块也提供了自定义字节顺序的功能,可以指定大端存储、小端存储等特定的字节顺序,对于底层通信的字节顺序是十分重要的,不同的字节顺序和存储方式也会导致字节大小的不同。在format字符串前面加上特定的符号即可以表示不同的字节顺序存储方式,例如采用小端存储 s = struct.Struct(‘<I3sf’)就可以了。
在这里插入图片描述
大端存储和小端存储
小端:较高的有效字节存放在较高的存储器地址,较低的有效字节存放在较低的存储器地址。
大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。

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()
    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))
    
# output
# Original values: (1, b'ab', 2.7)
# 
# Format string  : b'@ I 2s f' for native, native
# Uses           : 12 bytes
# Packed Value   : b'0100000061620000cdcc2c40'
# Unpacked Value : (1, b'ab', 2.700000047683716)
# 
# Format string  : b'= I 2s f' for native, standard
# Uses           : 10 bytes
# Packed Value   : b'010000006162cdcc2c40'
# Unpacked Value : (1, b'ab', 2.700000047683716)
# 
# Format string  : b'< I 2s f' for little-endian
# Uses           : 10 bytes
# Packed Value   : b'010000006162cdcc2c40'
# Unpacked Value : (1, b'ab', 2.700000047683716)
# 
# Format string  : b'> I 2s f' for big-endian
# Uses           : 10 bytes
# Packed Value   : b'000000016162402ccccd'
# Unpacked Value : (1, b'ab', 2.700000047683716)
# 
# Format string  : b'! I 2s f' for network
# Uses           : 10 bytes
# Packed Value   : b'000000016162402ccccd'
# Unpacked Value : (1, b'ab', 2.700000047683716)