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

时间:2011-09-28 15:14:08

标签: python string character-encoding python-3.x

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

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

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

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

6 个答案:

答案 0 :(得分:454)

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

  

bytearray([source [,encoding [,errors]]])

     

返回一个新的字节数组。 bytearray类型是0 <= x <0的范围内的可变整数序列。 256.它具有可变序列的大多数常用方法,在可变序列类型中描述,以及字节类型具有的大多数方法,参见字节和字节数组方法。

     

可选的source参数可用于以几种不同的方式初始化数组:

     

如果是字符串,您还必须提供编码(和可选的,错误)参数;然后,bytearray()使用str.encode()将字符串转换为字节。

     

如果是整数,则数组将具有该大小,并将使用空字节进行初始化。

     

如果它是符合缓冲区接口的对象,则该对象的只读缓冲区将用于初始化bytes数组。

     

如果它是可迭代的,则它必须是0&lt; = x&lt;范围内的整数可迭代。 256,用作数组的初始内容。

     

如果没有参数,则会创建一个大小为0的数组。

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

对于字符串的编码,我认为some_string.encode(encoding)比使用构造函数更Pythonic,因为它是最自我记录的 - “使用此字符串并使用此编码对其进行编码”比{{1更清晰 - 使用构造函数时没有显式动词。

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

另外,请参阅Serdalis的评论 - encode也更像Pythonic,因为它的反函数为unicode_string.encode(encoding),对称性很好。

答案 1 :(得分:218)

比想象的要容易:

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

答案 2 :(得分:82)

绝对最佳方式既不是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)

答案 3 :(得分:36)

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

a_string.encode()

你可以使用:

简单地将字节转换为字符串

some_bytes.decode()

bytes.decodestr.encodeencoding='utf-8'作为默认值。

以下功能(摘自Effective Python)可能有助于将str转换为bytesbytes转换为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

答案 4 :(得分:21)

回答一个稍微不同的问题:

您有一个保存在 str 变量中的原始 unicode 序列:

s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"

您需要能够获取该 unicode 的字节文字(对于 struct.unpack() 等)

s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'

解决方案:

s_new: bytes = bytes(s, encoding="raw_unicode_escape")

参考(向上滚动查看标准编码):

Python Specific Encodings

答案 5 :(得分:9)

so_string = 'stackoverflow'
so_bytes = so_string.encode( )