来自[Python 2.Docs]: struct - Interpret bytes as packed binary data:
此模块执行 Python 值和表示为 Python 字符串的 C 结构之间的转换。
这意味着它将把参数的内存表示打印为 char 序列。内存(以及其中的所有内容)是一个字节序列。每个字节都有一个值 [0..255](为简单起见,我使用 unsigned)。
因此,当它表示一个字节时,它将首先搜索一个 ASCII 代码与字节值匹配的 char,如果这样的 ( printable) char 找到,它将是那个字节的表示,否则表示将是 前面的字节值(在 hex 中) \x(表示不可打印的字符的约定)。作为旁注,(非扩展)ASCII char 的值介于 0 和 128 之间。
例子:
在进一步讨论之前,需要介绍一下字节序:这就是数据(在我们的例子中是数字)在计算机内存中的表示方式。几个链接(尽管可以在互联网上找到很多资源):
我将尝试简要解释 big 和 little endian 之间的区别(再次,为简单起见,我将坚持使用 8 位原子 仅元素大小)。
假设我们正在一张纸上做一些记忆表示练习,或者更好:在黑板上。如果我们将黑板表示为计算机内存,那么左上角将是它的开始(地址 0),并且地址会随着我们向右移动而增加(当我们到达右边缘时,也向下到下一行)。
我们希望将数字 0x12345678 表示为 4 字节数,从左上角开始(每个字节由正好2个十六进制数字组成):
╔═══════════╦══════════╦══════════╦══════════╦══════════╗
║ Byte ║ 01 ║ 02 ║ 03 ║ 04 ║
╠═══════════╬══════════╬══════════╬══════════╬══════════╣
║ Value ║ 0x12 ║ 0x34 ║ 0x56 ║ 0x78 ║
╚═══════════╩══════════╩══════════╩══════════╩══════════╝
我们数字的最重要字节存储在最低内存地址(以及最小有效字节存储在最高),即big endian。对于little endian,我们的字节数是相反的。
作为结论,人类认为“big endianly”。
我想讨论的另一个主题是:types(更准确地说是int)。 Python,基于 C,继承了它的原生类型,所以 int 将有 4 个字节(在某些平台上/ 可能有 8 的架构)。所以,一个int(同样是关于unsigned)有一个值[0..4294967295]。但即使对于较小的值:例如 5(只需要 1 个字节),它仍然会占用 4 个字节:(最重要的) 未使用的字节将用 0 填充。因此,我们作为 4 字节 unsigned int 的数字将是 (hex):0x00000005强>。
现在,回到我们的问题:如上所述,5 是 0x05(或 0x00000005 - 4 字节 unsigned int)或 chars em>:“\x00\x00\x00\x05”。但它与 struct.pack 显示的顺序相反;我想你已经猜到原因了:它是 little endian 表示。这是由给出的 1st (fmt) 参数(更准确地说是“”部分)给出的到[Python 2.Docs]: struct.pack(fmt, v1, v2, ...)(可能的值列在同一页上:[Python 2.Docs]: struct - Byte Order, Size, and Alignment)。
对于 55555,情况是一样的。它的hex表示为:0xd903或0x0000d903。
如果还没有意义,请使用这个稍微修改过的代码版本并使用它,为 data_set 输入不同的值并查看输出:
code.py:
import struct
fmt = "<L"
data_set = [5, 55555, 0x12345678]
for data in data_set:
output_str = "{} - {}".format(hex(data), repr(struct.pack(fmt, data)).strip("'")) # This is just for formatting output string to be displayed to the user
print(output_str) # Python3 compatible (however the formatting above won't behave nicely)
输出:
c:\Work\Dev\StackOverflow\q037990060>"C:\Install\x64\HPE\OPSWpython\2.7.10__00\python.exe" "code.py"
0x5 - \x05\x00\x00\x00
0xd903 - \x03\xd9\x00\x00
0x12345678 - xV4\x12