将整数转换为字节在Python 3中

2024-05-13 05:09:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在Python3中构建这个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问题中,我确实发现了一些令人惊讶的消息,关于将format添加到字节(另请参见Python 3 bytes formatting):

http://bugs.python.org/issue3982

This interacts even more poorly with oddities like bytes(int) returning zeroes now

以及:

It would be much more convenient for me if bytes(int) returned the ASCIIfication of that int; but honestly, even an error would be better than this behavior. (If I wanted this behavior - which I never have - I'd rather it be a classmethod, invoked like "bytes.zeroes(n)".)

有人能解释一下这种行为是从哪里来的吗?


Tags: 对象字节bytesmore方式bethispython3
3条回答

在Python3.2中,您可以

>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'

https://docs.python.org/3/library/stdtypes.html#int.to_bytes

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))。请注意,此编码仅适用于无符号(非负)整数。

您可以使用struct's pack

In [11]: struct.pack(">I", 1)
Out[11]: '\x00\x00\x00\x01'

“>;”是byte-order (big-endian),“I”是format character。因此,如果你想做其他事情,你可以具体地说:

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完成。

这就是它的设计方式——这是有意义的,因为通常,您会对iterable而不是单个整数调用bytes

>>> bytes([3])
b'\x03'

docs state this以及bytes的docstring:

 >>> help(bytes)
 ...
 bytes(int) -> bytes object of size given by the parameter initialized with null bytes

相关问题 更多 >