似乎有两种不同的方法可以将字符串转换为字节,如TypeError: 'str' does not support the buffer interface的答案所示
哪种方法会更好或更好Pythonic?或者只是个人偏好的问题?
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
答案 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.decode
和str.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
答案 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")
参考(向上滚动查看标准编码):
答案 5 :(得分:9)
so_string = 'stackoverflow'
so_bytes = so_string.encode( )