我试图在Python 3中构建这个bytes对象:
b'3\r\n'
所以我尝试了显而易见的(对我来说),发现了一个奇怪的行为:
>>> bytes(3) + b'\r\n'
b'\x00\x00\x00\r\n'
显然:
>>> bytes(10)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
在阅读文档时,我无法看到字节转换为什么以这种方式工作的任何指针。然而,我确实在这个Python问题中发现了一些关于向字节添加格式的令人惊讶的消息(另见Python 3字节格式化):
http://bugs.python.org/issue3982
这与bytes(int)返回零这样的奇怪情况的交互更加糟糕
and:
如果字节(int)返回该int的ASCIIfication,对我来说会更方便;但说实话,即使是一个错误也比这种行为要好。(如果我想要这种行为——我从来没有——我宁愿它是一个类方法,像“bytes.zero (n)”那样调用。)
谁能给我解释一下这种行为是怎么来的?
你可以使用结构体的包:
In [11]: struct.pack(">I", 1)
Out[11]: '\x00\x00\x00\x01'
“>”是字节顺序(大端序),“I”是格式字符。所以如果你想做别的事情,你可以具体一点:
In [12]: struct.pack("<H", 1)
Out[12]: '\x01\x00'
In [13]: struct.pack("B", 1)
Out[13]: '\x01'
这在python 2和python 3上都是一样的。
注意:反向操作(字节到int)可以通过unpack完成。
文件说:
bytes(int) -> bytes object of size given by the parameter
initialized with null bytes
序列:
b'3\r\n'
它是字符“3”(十进制51)、字符“\r”(13)和“\n”(10)。
因此,方法会这样对待它,例如:
>>> bytes([51, 13, 10])
b'3\r\n'
>>> bytes('3', 'utf8') + b'\r\n'
b'3\r\n'
>>> n = 3
>>> bytes(str(n), 'ascii') + b'\r\n'
b'3\r\n'
在IPython 1.1.0和Python 3.2.3上测试
你可以使用结构体的包:
In [11]: struct.pack(">I", 1)
Out[11]: '\x00\x00\x00\x01'
“>”是字节顺序(大端序),“I”是格式字符。所以如果你想做别的事情,你可以具体一点:
In [12]: struct.pack("<H", 1)
Out[12]: '\x01\x00'
In [13]: struct.pack("B", 1)
Out[13]: '\x01'
这在python 2和python 3上都是一样的。
注意:反向操作(字节到int)可以通过unpack完成。
3的ASCIIfication是“\x33”而不是“\x03”!
这就是python对str(3)所做的,但对字节来说是完全错误的,因为它们应该被认为是二进制数据的数组,而不应该被滥用为字符串。
实现您想要的最简单的方法是bytes((3,)),这比bytes([3])更好,因为初始化列表的代价要高得多,所以当您可以使用元组时,永远不要使用列表。可以使用int转换更大的整数。“小”,to_bytes(3)。
初始化具有给定长度的字节是有意义的,也是最有用的,因为它们通常用于创建某种类型的缓冲区,为此需要分配一定大小的内存。我经常在初始化数组或通过写入零来扩展某个文件时使用这个方法。