我想使用struct.unpack()
从Python 2.7中的字节字符串中获取长值,但我发现了一些奇怪的行为,我想知道这是不是一个bug,还有,我是什么可以做到这一点。
以下是:
import struct
>>> struct.unpack("L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 8
这是预期的行为。它需要一个8字节的字符串来提取8字节的长值。
现在我将字节顺序更改为网络字节顺序,我得到以下内容:
>>> struct.unpack("!L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4
突然间,它只需要4个字节作为8字节长的值。
该怎么做,我该怎么做才能解决这个问题?
答案 0 :(得分:1)
这里的问题是,第一种情况是struct
使用计算机的本机long
大小,第二种情况是使用struct
的“标准” long
大小。
在第一个示例中,您未指定byte-order, size, and alignment specifier(@=<>!
中的一个),因此struct
假设'@'
使用了计算机的本机值,即机器的本机long
大小。为了在各个平台上保持一致,struct
defines standard sizes for each type可能与您计算机的本机大小不同。除'@'
以外的每个说明符都使用这些标准尺寸。
因此,在long
的情况下,struct
的标准是4个字节,这就是'!L'
(或任何'[=<>!]L'
期望有4个字节的原因。机器的本机long
显然是8个字节,这就是'@L'
或'L'
期望为8的原因。如果要使用机器的本机字节顺序,但仍与{{1}兼容}的标准尺寸,我建议您使用struct
指定所有格式,而不要让Python将其默认设置为'='
。
您可以使用'@'
来检查尺寸期望值,即:
struct.calcsize
(这在我的64位Windows 10计算机上返回>>> struct.calcsize('@L'), struct.calcsize('=L')
,但在我的64位Ubuntu 16.04计算机上返回(4, 4)
。)
您还可以通过编译(8, 4)
脚本来检查C
的值来直接检查计算机的类型大小,例如:
sizeof(long)
我跟随this guide在Windows 10计算机上编译了#include <stdio.h>
int main()
{
printf("%li",sizeof(long));
return 0;
}
脚本。