在Python 3中将int转换为字节

 浮尘所惑的猫猫 发布于 2023-02-04 20:40

我试图在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'

我一直无法看到任何关于为什么字节转换以这种方式阅读文档的指针.但是,我确实在Python问题中发现了一些关于添加format字节的惊喜消息(另请参阅Python 3字节格式化):

http://bugs.python.org/issue3982

这与奇怪的事情(如字节(int)现在返回零)的交互更加糟糕

和:

如果bytes(int)返回该int的ASCIIfication,对我来说会更方便; 但老实说,即使错误也会比这种行为更好.(如果我想要这种行为 - 我从来没有 - 我宁愿它是一个类方法,调用类似"bytes.zeroes(n)".)

有人可以解释一下这种行为来自哪里?

7 个回答
  • 你可以使用struct的包:

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

    ">"是字节顺序(big-endian),"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)可以通过解压缩来完成.

    2023-02-04 20:42 回答
  • 从python 3.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)).

    2023-02-04 20:42 回答
  • 3的ASCII化"\x33"不是"\x03"!

    这就是python所做的,str(3)但是字节完全错误,因为它们应该被认为是二进制数据的数组而不是被滥用为字符串.

    实现您想要的最简单的方法是bytes((3,)),这比bytes([3])因为初始化列表要贵得多,所以在使用元组时永远不要使用列表.您可以使用转换更大的整数int.to_bytes(3, "little").

    初始化具有给定长度的字节是有意义的并且是最有用的,因为它们通常用于创建某种类型的缓冲区,您需要为其分配给定大小的内存.我经常在初始化数组或通过向其写入零来扩展某些文件时使用它.

    2023-02-04 20:42 回答
  • 这就是它的设计方式 - 它是有道理的,因为通常,你会调用bytes一个可迭代而不是一个整数:

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

    该文档说明这一点,以及文档字符串为bytes:

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

    2023-02-04 20:42 回答
  • 文件说:

    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上测试过

    2023-02-04 20:43 回答
  • Python 3.5+ printf为字节引入了%-interpolation(样式格式):

    >>> b'%d\r\n' % 3
    b'3\r\n'
    

    请参阅PEP 0461 - 将%格式添加到字节和bytearray.

    在早期版本中,您可以使用str.encode('ascii')结果:

    >>> s = '%d\r\n' % 3
    >>> s.encode('ascii')
    b'3\r\n'
    

    注:这是从不同的东西int.to_bytes产生:

    >>> n = 3
    >>> n.to_bytes((n.bit_length() + 7) // 8, 'big') or b'\0'
    b'\x03'
    >>> b'3' == b'\x33' != '\x03'
    True
    

    2023-02-04 20:43 回答
  • int(包括Python2 long)可以转换为bytes使用以下函数:

    import codecs
    
    def int2bytes(i):
        hex_value = '{0:x}'.format(i)
        # make length of hex_value a multiple of two
        hex_value = '0' * (len(hex_value) % 2) + hex_value
        return codecs.decode(hex_value, 'hex_codec')
    

    反向转换可以由另一个完成:

    import codecs
    import six  # should be installed via 'pip install six'
    
    long = six.integer_types[-1]
    
    def bytes2int(b):
        return long(codecs.encode(b, 'hex_codec'), 16)
    

    这两个函数都适用于Python2和Python3.

    2023-02-04 20:43 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有