为什么我的struct.pack打印字符串而不是二进制流?
var = struct.pack('hhl3sf', 1, 2, 3, 'm6y', 2.7)
print repr(var)
输出为:
'\x01\x00\x02\x00\x03\x00\x00\x00m6y\x00\xcd\xcc,@'
是否应将'm6y'打印为\ x6d \ x36 \ x79?如果不是,我如何直接从包装中以她的身份打印或仅以普通二进制文件打印? 为什么在末尾使用char @ print?谢谢。
我尝试将所有值转换为ascii,然后以十六进制打印。 并同时运行binascii.hexlify。 它们都可以工作,但是我想知道为什么pack无法自动执行此操作。谢谢。
map(lambda c: ord(c), var)
map(lambda i: hex(i), map(lambda c: ord(c), var))
print 'Packed value : ', binascii.hexlify(var)
答案 0 :(得分:1)
Python的默认表示形式将字节串打印为ascii字符(在可能的情况下),并且只有在\x
不能转义时才打印。
通常希望将'm6y'
打印为\x6d\x36\x79
,但这不是它的工作原理。
如果您想看到变量全部显示为十六进制,则需要自己执行。例如:
>>> "".join("{0:02x}".format(b) for b in var)
'01000200030000006d367900cdcc2c40'
>>> print("".join("\\0x{0:02x}".format(b) for b in var))
\0x01\0x00\0x02\0x00\0x03\0x00\0x00\0x00\0x6d\0x36\0x79\0x00\0xcd\0xcc\0x2c\0x40
由您决定如何看待它。字节串通常是ascii字符,默认情况下将b"Hello world"
显示为
\0x48\0x65\0x6c\0x6c\0x6f\0x20\0x77\0x6f\0x72\0x6c\0x64
不友好。
答案 1 :(得分:0)
字符串打印问题
在[SO]: Python struct.pack() behavior (@CristiFati's answer)(在开头的某个地方)中,我尝试简要解释该行为。基本上,当向用户显示一些内存内容时,如果某个字节具有相应的可打印字符,则使用该字符(请注意,这仅用于表示,它不会影响内存内容) 。
如果要绕过此行为,则必须手动进行(有很多方法-我不会坚持使用它们)。但请记住,这样做,生成的字符串将与原始字符串不相同:
>>> b0 = b"\x41" >>> b0 b'A' >>> len(b0) 1 >>> >>> b1 = "".join(("\\x{:02X}".format(c) for c in b0)) >>> b1 '\\x41' >>> len(b1) 4
结束字符问题
发布[Python 3.Docs]: struct - Interpret bytes as packed binary data页面。
用简单的问题解决问题,并分别解决每个问题:
结果字符串末尾的' @ ' char ( 0x40 ): 它是 2.7 表示的一部分:
>>> import struct >>> >>> s0 = struct.pack(b"f", 2.7) >>> s0 b'\xcd\xcc,@' >>> len(s0) 4 >>> >>> s1 = struct.pack(b"f", 1.7) >>> s1 b'\x9a\x99\xd9?' >>> len(s1) 4
我相信混淆是由最后一个' \ x00 '字节(var[-5]
)引起的:
>>> struct.pack(b"3sI", b"ABC", 0xFFFFFFFF) b'ABC\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"@3sI", b"ABC", 0xFFFFFFFF) b'ABC\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"=3sI", b"ABC", 0xFFFFFFFF) b'ABC\xff\xff\xff\xff' >>> >>> >>> struct.pack(b"4sI", b"ABCD", 0xFFFFFFFF) b'ABCD\xff\xff\xff\xff' >>> >>> struct.pack(b"1sI", b"A", 0xFFFFFFFF) b'A\x00\x00\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"1sH", b"A", 0xFFFF) b'A\x00\xff\xff' >>> >>> struct.pack(b"1sB", b"A", 0xFF) b'A\xff' >>> >>> struct.pack(b"1sd", b"A", 2.7) b'A\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\x05@'
从以上示例中可以看出,与我们的 float 数字没有任何关系,但是与前面的字符串有关,这是 alignment (对于 float 是 4 个字节)。检查[Wikipedia]: Data structure alignment了解更多详情