Python 这两段代码之间的区别是什么

Python 这两段代码之间的区别是什么,python,struct,Python,Struct,大家好,我有两段代码,让我困惑的是,虽然它们应该是等效的,但在运行这两段代码时,我没有收到相同的结果,它们之间有什么区别 以下是第一部分和工作部分: packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload # packet = struct.pack(">B", relayCmd) # packet += struct.pack("H", 0) # pa

大家好,我有两段代码,让我困惑的是,虽然它们应该是等效的,但在运行这两段代码时,我没有收到相同的结果,它们之间有什么区别

以下是第一部分和工作部分:

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload
#     packet = struct.pack(">B", relayCmd)
#     packet += struct.pack("H", 0)
#     packet += struct.pack("H", streamId)
#     packet += struct.pack("L", 0)
#     packet += struct.pack("H", len(payload))
#     packet += payload
第二非工作部分:

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload
#     packet = struct.pack(">B", relayCmd)
#     packet += struct.pack("H", 0)
#     packet += struct.pack("H", streamId)
#     packet += struct.pack("L", 0)
#     packet += struct.pack("H", len(payload))
#     packet += payload

在第一个版本中,通过“>”将格式指定为Big-Endian,然后所有格式参数都以这种方式编码。在第二个示例中,您仅在第一行中指定Big-Endian,然后使用系统的本机编码对所有其他参数进行编码(“@”作为默认值)。

在第一个版本中,您通过“>”将格式指定为Big-Endian,然后以这种方式对所有格式参数进行编码。在第二个示例中,您仅在第一行中指定Big-Endian,然后使用系统的本机编码对所有其他参数进行编码(“@”用作默认值)。

来自
struct
文档:

注意:默认情况下,打包给定C结构的结果包括pad字节,以保持所涉及的C类型的正确对齐;同样,在拆包时也要考虑对齐。选择此行为是为了使压缩结构的字节与相应C结构的内存布局完全对应。要处理与平台无关的数据格式或省略隐式pad字节,请使用
标准
大小和对齐方式,而不是
本机
大小和对齐方式:有关详细信息,请参见字节顺序、大小和对齐方式

当您没有为另外4行指定对齐方式时,您使用了默认的
@
对齐方式(使用
本机对齐方式)。您仅对第一个
relayCmd
codepoint使用了
标准对齐方式

因此,生产的尺寸不同:

>>> import struct
>>> struct.calcsize('>BHHLH')
11
>>> struct.calcsize('>B')
1
>>> struct.calcsize('H')
2
>>> struct.calcsize('L')
8
>>> 1 + 3 * 2 + 8
15
区别在于填充的
L
;如果对所有
pack()
调用使用
大端字符标记,则只需四个字节:

所以这是可行的:

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

struct
文档中:

注意:默认情况下,打包给定C结构的结果包括pad字节,以保持所涉及的C类型的正确对齐;同样,在拆包时也要考虑对齐。选择此行为是为了使压缩结构的字节与相应C结构的内存布局完全对应。要处理与平台无关的数据格式或省略隐式pad字节,请使用
标准
大小和对齐方式,而不是
本机
大小和对齐方式:有关详细信息,请参见字节顺序、大小和对齐方式

当您没有为另外4行指定对齐方式时,您使用了默认的
@
对齐方式(使用
本机对齐方式)。您仅对第一个
relayCmd
codepoint使用了
标准对齐方式

因此,生产的尺寸不同:

>>> import struct
>>> struct.calcsize('>BHHLH')
11
>>> struct.calcsize('>B')
1
>>> struct.calcsize('H')
2
>>> struct.calcsize('L')
8
>>> 1 + 3 * 2 + 8
15
区别在于填充的
L
;如果对所有
pack()
调用使用
大端字符标记,则只需四个字节:

所以这是可行的:

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

你必须在每个字母前面加上
,这样所有的字母都是大端的

#!/usr/bin/env python2

import struct

relayCmd = 170
streamId = 10000
payload = "A"

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))

你必须在每个字母前面加上
,这样所有的字母都是大端的

#!/usr/bin/env python2

import struct

relayCmd = 170
streamId = 10000
payload = "A"

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))