Python标准库笔记(8) — pprint模块


声明:本文转载自https://my.oschina.net/jhao104/blog/1797706,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

struct模块提供了用于在字节字符串和Python原生数据类型之间转换函数,比如数字和字符串。

  该模块作用是完成Python数值和C语言结构体的Python字符串形式间的转换。 这可以用于处理存储在文件中或从网络连接中存储的二进制数据,以及其他数据源。

1. 模块函数和Struct类

  它除了提供一个Struct类之外,还有许多模块级的函数用于处理结构化的值。这里有个格式符(Format specifiers)的概念,是指从字符串格式转换为已编译的表示形式,类似于正则表达式的处理方式。通常实例化Struct类,调用类方法来完成转换,比直接调用模块函数有效的多。下面的例子都是使用Struct类。

2. Packing(打包)和Unpacking(解包)

  Struct支持将数据packing(打包)成字符串,并能从字符串中逆向unpacking(解压)出数据。

  在本例中,格式指定器(specifier)需要一个整型或长整型,一个两个字节的string,和一个浮点数。格式符中的空格用于分隔各个指示器(indicators),在编译格式时会被忽略。

import struct  import binascii  values = (1, 'ab'.encode('utf-8'), 2.7) s = struct.Struct('I 2s f') packed_data = s.pack(*values)  print('原始值:', values) print('格式符:', s.format) print('占用字节:', s.size) print('打包结果:', binascii.hexlify(packed_data)) 

# output 原始值: (1, b'ab', 2.7) 格式符: b'I 2s f' 占用字节: 12 打包结果: b'0100000061620000cdcc2c40' 

  这个示例将打包的值转换为十六进制字节序列,用binascii.hexlify()方法打印出来。

  使用unpack()方法解包。

import struct import binascii  packed_data = binascii.unhexlify(b'0100000061620000cdcc2c40')  s = struct.Struct('I 2s f') unpacked_data = s.unpack(packed_data) print('解包结果:', unpacked_data) 

# output 解包结果: (1, b'ab', 2.700000047683716) 

  将打包的值传给unpack(),基本上返回相同的值(浮点数会有差异)。

3. 字节顺序/大小/对齐

  默认情况下,pack是使用本地C库的字节顺序来编码的。格式化字符串的第一个字符可以用来表示填充数据的字节顺序、大小和对齐方式,如下表所描述的:

CharacterByte orderSizeAlignment
@本地本地本地
=本地standardnone
<little-endian(小字节序)standardnone
>big-endian(大字节序)standardnone
!network (= big-endian)standardnone

  如果格式符中没有设置这些,那么默认将使用 @

  本地字节顺序是指字节顺序是由当前主机系统决定。比如:Intel x86和AMD64(x86-64)使用小字节序; Motorola 68000和 PowerPC G5使用大字节序。ARM和Intel安腾支持切换字节序。可以使用sys.byteorder查看当前系统的字节顺序。

  本地大小(Size)和对齐(Alignment)是由c编译器的sizeof表达式确定的。它与本地字节顺序对应。

  标准大小由格式符确定,下面会讲各个格式的标准大小。

示例:

import struct import binascii  values = (1, 'ab'.encode('utf-8'), 2.7) print('原始值  : ', 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('格式符  : ', s.format, 'for', name)     print('占用字节: ', s.size)     print('打包结果: ', binascii.hexlify(packed_data))     print('解包结果: ', s.unpack(packed_data)) 

# output 原始值  :  (1, b'ab', 2.7)  格式符  :  b'@ I 2s f' for native, native 占用字节:  12 打包结果:  b'0100000061620000cdcc2c40' 解包结果:  (1, b'ab', 2.700000047683716)  格式符  :  b'= I 2s f' for native, standard 占用字节:  10 打包结果:  b'010000006162cdcc2c40' 解包结果:  (1, b'ab', 2.700000047683716)  格式符  :  b'< I 2s f' for little-endian 占用字节:  10 打包结果:  b'010000006162cdcc2c40' 解包结果:  (1, b'ab', 2.700000047683716)  格式符  :  b'> I 2s f' for big-endian 占用字节:  10 打包结果:  b'000000016162402ccccd' 解包结果:  (1, b'ab', 2.700000047683716)  格式符  :  b'! I 2s f' for network 占用字节:  10 打包结果:  b'000000016162402ccccd' 解包结果:  (1, b'ab', 2.700000047683716) 

4. 格式符

格式符对照表如下:

FormatC TypePython typeStandard sizeNotes
xpad byteno value
ccharbytes of length 11
bsigned charinteger1(1),(3)
Bunsigned charinteger1(3)
?_Boolbool1(1)
hshortinteger2(3)
Hunsigned shortinteger2(3)
iintinteger4(3)
Iunsigned intinteger4(3)
llonginteger4(3)
Lunsigned longinteger4(3)
qlong longinteger8(2), (3)
Qunsigned long longinteger8(2), (3)
nssize_tinteger(4)
Nsize_tinteger(4)
ffloatfloat4(5)
ddoublefloat8(5)
schar[]bytes
pchar[]bytes
Pvoid *integer(6)

5. 缓冲区

  将数据打包成二进制通常是用在对性能要求很高的场景。 在这类场景中可以通过避免为每个打包结构分配新缓冲区的开销来优化。 pack_into()unpack_from()方法支持直接写入预先分配的缓冲区。

import array import binascii import ctypes import struct  s = struct.Struct('I 2s f') values = (1, 'ab'.encode('utf-8'), 2.7) print('原始值:', values)  print() print('使用ctypes模块string buffer')  b = ctypes.create_string_buffer(s.size) print('原始buffer  :', binascii.hexlify(b.raw)) s.pack_into(b, 0, *values) print('打包结果写入 :', binascii.hexlify(b.raw)) print('解包        :', s.unpack_from(b, 0))  print() print('使用array模块')  a = array.array('b', b'\0' * s.size) print('原始值   :', binascii.hexlify(a)) s.pack_into(a, 0, *values) print('打包写入 :', binascii.hexlify(a)) print('解包     :', s.unpack_from(a, 0)) 

# output 原始值: (1, b'ab', 2.7)  使用ctypes模块string buffer 原始buffer  : b'000000000000000000000000' 打包结果写入 : b'0100000061620000cdcc2c40' 解包        : (1, b'ab', 2.700000047683716)  使用array模块 原始值   : b'000000000000000000000000' 打包写入 : b'0100000061620000cdcc2c40' 解包     : (1, b'ab', 2.700000047683716) 

首发地址: Python标准库笔记(6) — struct模块

本文发表于2018年04月19日 22:38
(c)注:本文转载自https://my.oschina.net/jhao104/blog/1797706,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2248 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1