Python struct.pack 不一致
Python struct.pack is not consistent
我正在使用 struct.pack 来 return 我一个字节对象。然而,这是不一致的。
print(struct.pack('BbbB', 0x1B, -2, 1, 0)) #returns b'\x1b\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0F, -2, 1, 0)) #returns b'\x0f\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0C, -2, 1, 0)) #returns b'\x0c\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x35, -2, 1, 0)) #returns b'5\xfe\x01\x00' ???
print(struct.pack('BbbB', 0x21, -2, 1, 0)) #returns b'!\xfe\x01\x00' ???
如果我查看 ASCII character chart,我就能明白为什么它变成了“5”和“!”在最后两个例子中,但它不应该 returned 我 b'\0x35\xfe\x01\x00' 和 b'\0x21\xfe\x01\x00' 而不是上面的结果?我在这里错过了什么?
我正在使用 Python 3.7.0.
不一致的不是包。让你困惑的是打印功能。
两者都是 '!' (ascii value 33, hexadecimal 0x21) and '5' (ascii value 53, hexadecimal 0x35) 是可打印字符,所以它们只是正常打印。但是其他字节不可打印,所以 python 求助于打印它们的十六进制表示,这样你至少可以看到 一些有意义的东西 。
字节值是您期望的值,不用担心。
看看这个:
>>> b'\x35\xfe\x01\x00'
b'5\xfe\x01\x00'
>>> b'\x35\xfe\x01\x00' == b'5\xfe\x01\x00'
True
>>> b'\x35'
b'5'
>>> b'\x35' == b'5'
True
>>> b'\x35'[0]
53
>>> b'5'[0]
53
b'\x35'
和 b'5'
都具有相同的字节值 0x35。只是它们都是相同值的两个不同表示。
对于同一个实际值,有多种写字面值的方法是很常见的。例如,十进制值 53 可以用 53
、0x35
、0o65
或 0b110101
表示。这是同一个 int
对象的所有数字文字。
就像那样,b'\x35
和 b'5'
只是同一字节对象的两个字节串文字。
打印出对象时,Python 在内部调用对象 str()
以确保对象可打印。对于 bytes 对象,这意味着将返回一个 bytes 字符串文字。由于有多种方式来表示该对象,Python 必须决定一种表示方式。
对于字节,规则很简单,只要一个字节可以表示为可打印的 ASCII 字符,就使用该字符而不是转义序列。这通常允许您 读取 表示 ASCII 数据的字节字符串。例如 b'foo'
比 b'\x66\x6f\x6f'
更具可读性(但 意味着 相同)。
如果您需要获得字节对象的一致字符串表示,您可以将其显式转换为十六进制字符串。例如通过调用 bytes.hex
:
>>> b'5\xfe\x01\x00'.hex()
'35fe0100'
当然,现在这不再是二进制数据,而是一个字符串表示二进制数据,编码为十六进制字符串。如果你想实际传输数据,例如通过网络或文件内部,你将希望将其保留为 bytes
对象并使用它。
我正在使用 struct.pack 来 return 我一个字节对象。然而,这是不一致的。
print(struct.pack('BbbB', 0x1B, -2, 1, 0)) #returns b'\x1b\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0F, -2, 1, 0)) #returns b'\x0f\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x0C, -2, 1, 0)) #returns b'\x0c\xfe\x01\x00' GOOD
print(struct.pack('BbbB', 0x35, -2, 1, 0)) #returns b'5\xfe\x01\x00' ???
print(struct.pack('BbbB', 0x21, -2, 1, 0)) #returns b'!\xfe\x01\x00' ???
如果我查看 ASCII character chart,我就能明白为什么它变成了“5”和“!”在最后两个例子中,但它不应该 returned 我 b'\0x35\xfe\x01\x00' 和 b'\0x21\xfe\x01\x00' 而不是上面的结果?我在这里错过了什么?
我正在使用 Python 3.7.0.
不一致的不是包。让你困惑的是打印功能。
两者都是 '!' (ascii value 33, hexadecimal 0x21) and '5' (ascii value 53, hexadecimal 0x35) 是可打印字符,所以它们只是正常打印。但是其他字节不可打印,所以 python 求助于打印它们的十六进制表示,这样你至少可以看到 一些有意义的东西 。
字节值是您期望的值,不用担心。
看看这个:
>>> b'\x35\xfe\x01\x00'
b'5\xfe\x01\x00'
>>> b'\x35\xfe\x01\x00' == b'5\xfe\x01\x00'
True
>>> b'\x35'
b'5'
>>> b'\x35' == b'5'
True
>>> b'\x35'[0]
53
>>> b'5'[0]
53
b'\x35'
和 b'5'
都具有相同的字节值 0x35。只是它们都是相同值的两个不同表示。
对于同一个实际值,有多种写字面值的方法是很常见的。例如,十进制值 53 可以用 53
、0x35
、0o65
或 0b110101
表示。这是同一个 int
对象的所有数字文字。
就像那样,b'\x35
和 b'5'
只是同一字节对象的两个字节串文字。
打印出对象时,Python 在内部调用对象 str()
以确保对象可打印。对于 bytes 对象,这意味着将返回一个 bytes 字符串文字。由于有多种方式来表示该对象,Python 必须决定一种表示方式。
对于字节,规则很简单,只要一个字节可以表示为可打印的 ASCII 字符,就使用该字符而不是转义序列。这通常允许您 读取 表示 ASCII 数据的字节字符串。例如 b'foo'
比 b'\x66\x6f\x6f'
更具可读性(但 意味着 相同)。
如果您需要获得字节对象的一致字符串表示,您可以将其显式转换为十六进制字符串。例如通过调用 bytes.hex
:
>>> b'5\xfe\x01\x00'.hex()
'35fe0100'
当然,现在这不再是二进制数据,而是一个字符串表示二进制数据,编码为十六进制字符串。如果你想实际传输数据,例如通过网络或文件内部,你将希望将其保留为 bytes
对象并使用它。