首页 文章

在Python 3中将字符串转换为字节的最佳方法?

提问于
浏览
490

似乎有两种不同的方法将字符串转换为字节,如TypeError: 'str' does not support the buffer interface的答案所示

哪种方法更好或更好Pythonic?或者只是个人偏好的问题?

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')

5 回答

  • 32

    它比想象的容易:

    my_str = "hello world"
    my_str_as_bytes = str.encode(my_str)
    type(my_str_as_bytes) # ensure it is byte representation
    my_decoded_str = my_str_as_bytes.decode()
    type(my_decoded_str) # ensure it is string representation
    
  • 396

    如果您查看 bytes 的文档,它会指向bytearray

    bytearray([source [,encoding [,errors]]])返回一个新的字节数组 . bytearray类型是0 <= x <256范围内的可变整数序列 . 它具有可变序列的大多数常用方法,在可变序列类型中描述,以及字节类型具有的大多数方法,请参阅字节和字节数组方法 . 可选的source参数可用于以几种不同的方式初始化数组:如果它是一个字符串,您还必须提供编码(和可选的,错误)参数;然后,bytearray()使用str.encode()将字符串转换为字节 . 如果它是一个整数,则该数组将具有该大小,并将使用空字节进行初始化 . 如果它是符合缓冲区接口的对象,则将使用该对象的只读缓冲区来初始化bytes数组 . 如果它是可迭代的,则它必须是0 <= x <256范围内的整数可迭代,它们用作数组的初始内容 . 如果没有参数,则会创建一个大小为0的数组 .

    所以 bytes 可以做的不仅仅是编码一个字符串 . 它是Pythonic,它允许你用任何类型的有意义的源参数调用构造函数 .

    对于编码字符串,我认为 some_string.encode(encoding) 比使用构造函数更Pythonic,因为它是最自我的文档 - "take this string and encode it with this encoding"比 bytes(some_string, encoding) 更清晰 - 当你使用构造函数时没有明确的动词 .

    Edit: 我检查了Python源代码 . 如果使用CPython将unicode字符串传递给 bytes ,则会调用PyUnicode_AsEncodedString,这是 encode 的实现;所以如果你自己打电话给_635223,你就是在跳过一个间接层 .

    另外,请参阅Serdalis的评论 - unicode_string.encode(encoding) 也更像Pythonic,因为它的反面是 byte_string.decode(encoding) 并且对称性很好 .

  • 170

    绝对最好的方式既不是2,也不是3 . 自Python 3.0以来,encode的第一个参数默认为 'utf-8' . 因此最好的方法是

    b = mystring.encode()
    

    这也会更快,因为默认参数不会导致C代码中的字符串 "utf-8" ,而是 NULL ,这要检查得快得多!

    这里有一些时间:

    In [1]: %timeit -r 10 'abc'.encode('utf-8')
    The slowest run took 38.07 times longer than the fastest. 
    This could mean that an intermediate result is being cached.
    10000000 loops, best of 10: 183 ns per loop
    
    In [2]: %timeit -r 10 'abc'.encode()
    The slowest run took 27.34 times longer than the fastest. 
    This could mean that an intermediate result is being cached.
    10000000 loops, best of 10: 137 ns per loop
    

    尽管有警告,但在重复运行后时间非常稳定 - 偏差仅为~2% .


    使用不带参数的 encode() 不兼容Python 2,因为在Python 2中默认的字符编码是ASCII .

    >>> 'äöä'.encode()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
    
  • 8

    您可以使用以下命令将字符串转换为字节

    a_string.encode()

    您可以使用以下命令将字节转换为字符串:

    some_bytes.decode()

    bytes.decodestr.encode 具有 encoding='utf-8' 作为默认值 .

    以下函数(取自Effective Python)可能有助于将 str 转换为 bytes 并将 bytes 转换为 str

    def to_bytes(bytes_or_str):
        if isinstance(bytes_or_str, str):
            value = bytes_or_str.encode() # uses 'utf-8' for encoding
        else:
            value = bytes_or_str
        return value # Instance of bytes
    
    
    def to_str(bytes_or_str):
        if isinstance(bytes_or_str, bytes):
            value = bytes_or_str.decode() # uses 'utf-8' for encoding
        else:
            value = bytes_or_str
        return value # Instance of str
    
  • 51
    so_string = 'stackoverflow'
    so_bytes = so_string.encode( )
    

相关问题