为什么 "bytes(n)" 创建一个长度为 n 的字节字符串,而不是将 n 转换为二进制表示形式?
为什么 "bytes(n)" 创建一个长度为 n 的字节字符串,而不是将 n 转换为二进制表示形式?
我试图在Python 3中构建这个字节对象:
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'
我一直无法从文档中找到有关字节转换以这种方式工作的指针。然而,在这个关于在字节中添加format
的Python问题中,我发现了一些令人惊讶的消息(参见Python 3 bytes formatting):
http://bugs.python.org/issue3982
这与字节(int)返回零的奇怪行为更加不兼容
还有:
如果字节(int)返回该int的ASCIIfication,那对我来说会更方便;但是,即使是错误行为也比这个行为更好。(如果我想要这个行为-我从来没有-我宁愿它是一个类方法,像“bytes.zeroes(n)”一样调用。)
有人能解释一下这种行为是从哪里来的吗?
admin 更改状态以发布 2023年5月23日
这样设计是有道理的,因为通常你会对一个可迭代对象调用 bytes
而不是单独的整数:
>>> bytes([3]) b'\x03'
Python 文档中有提到这一点,而且 bytes
函数的文档字符串也是这么写的:
>>> help(bytes) ... bytes(int) -> bytes object of size given by the parameter initialized with null bytes
从Python 3.2开始,您可以使用to_bytes
:
>>> (1024).to_bytes(2, byteorder='big') b'\x04\x00'
def int_to_bytes(x: int) -> bytes: return x.to_bytes((x.bit_length() + 7) // 8, 'big') def int_from_bytes(xbytes: bytes) -> int: return int.from_bytes(xbytes, 'big')
因此,x == int_from_bytes(int_to_bytes(x))
。
请注意,上述编码仅适用于无符号(非负)整数。
对于有符号整数,位长度计算要稍微复杂一些:
def int_to_bytes(number: int) -> bytes: return number.to_bytes(length=(8 + (number + (number < 0)).bit_length()) // 8, byteorder='big', signed=True) def int_from_bytes(binary_data: bytes) -> Optional[int]: return int.from_bytes(binary_data, byteorder='big', signed=True)