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

在Python3中将字符串转换为字节的最佳方法?,python,string,character-encoding,python-3.x,Python,String,Character Encoding,Python 3.x,将字符串转换为字节似乎有两种不同的方法,如 这些方法中哪一种更好或更具Pythonic?还是只是个人喜好的问题 b = bytes(mystring, 'utf-8') b = mystring.encode('utf-8') 如果您查看文档中的字节,它会指出: bytearray[源[,编码[,错误]] 返回一个新的字节数组。bytearray类型是一个范围为0的可变整数序列,比想象的要简单: my_str = "hello world" my_str_as_bytes = str.enc

将字符串转换为字节似乎有两种不同的方法,如

这些方法中哪一种更好或更具Pythonic?还是只是个人喜好的问题

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

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

如果您查看文档中的字节,它会指出:

bytearray[源[,编码[,错误]]


返回一个新的字节数组。bytearray类型是一个范围为0的可变整数序列,比想象的要简单:

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
绝对最好的方法不是这两种,而是第三种。自Python 3.0以来的第一个默认参数为“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


回答稍微不同的问题:

您有一个原始unicode序列,该序列已保存到str变量中:

s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"
您需要能够为struct.unpack等获取unicode的字节文本

s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'
解决方案:

s_new: bytes = bytes(s, encoding="raw_unicode_escape")
标准编码的参考向上滚动:



+1用于从python文档中获得一个好的参数和引用。另外,当您想要回字符串时,unicode_string.encodeencoding与bytearray.decodeCoding非常匹配。当您需要可变对象时,将使用bytearray。对于简单的str,您不需要它↔字节转换。@EugeneHomyakov这与bytearray无关,只是bytes的文档没有给出详细信息,他们只是说这是bytearray的不可变版本,所以我不得不引用。请注意,如果您试图将二进制数据转换为字符串,您很可能需要使用诸如byte_string之类的东西。由于utf-8不能覆盖整个范围0x00到0xFF 0-255,请查看python以获取更多信息。tl;dr会很有帮助,因为编码/解码更常见,而且可能更清晰。@Lennartreegebro我驳回。即使它更常见,读取字节我知道它在做什么,而编码并不会让我觉得它是在编码字节。@erm3nda这是一个很好的理由使用它,直到它感觉像那样,那么你离Unicode zen更近了一步。@LennartRegebro我感觉很好,可以只使用bytesitem,utf8,因为显式比隐式好,所以。。。默认情况下,str.encode默认为字节,这使您的zen更为Unicode,但不太明确。我也不喜欢用“普通”这个词。此外,字节项utf8更像str和bstring符号。如果我无法理解你的理由,我深表歉意。谢谢。@erm3nda如果您阅读了接受的答案,您可以看到encode不调用字节,相反。当然,这不是很明显,这就是为什么我问这个问题。他知道怎么做,他只是问哪种方式更好。请重新阅读问题。仅供参考:str.decodebytes对我不起作用Python 3.3.3说类型对象“str”没有属性“decode”,我使用的是bytes.decodeinstead@Mike:使用obj.method语法而不是cls.methodobj语法,即使用bytestring=unicode\u text.encodecoding和unicode\u text=bytestring.decodeconding。。。。i、 你不必要地创建了一个未绑定的方法,然后调用它作为第一个传递selfargument@KolobCanyon这个问题已经展示了正确的方法,即调用encode作为字符串上的绑定方法。这个答案建议您应该调用unbound方法并将字符串传递给它。这是答案中唯一的新信息,这是错误的。这里只有相当大的区别,因为a字符串是纯ASCII,这意味着内部存储已经是UTF-8版本,因此查找编解码器几乎是所有涉及的唯一成本,而b字符串很小,因此即使您必须编码,这没什么区别。用“\u00012345”*10000试试。两者都可以在我的笔记本电脑上占用28.8us;额外的50纳秒可能在舍入误差中丢失。当然,这是一个非常极端的例子,但“abc”在相反的方向上也同样极端。@abarnert-true,但即使如此,也没有理由将参数作为字符串传递。根据这一点,默认参数永远是做事情的最佳方式,对吗?如果这是关于讨论C代码的话,这种速度分析可能会觉得有些夸张。在解释性语言中,这让我哑口无言。如果显式键入默认参数值,你将一无所获——击键次数越多,代码越大,速度也越慢。Python的Zen声明显式优于隐式,这意味着最好使用显式“utf-8”参数。但您已经明确表明,去掉参数更快。这就是一个很好的答案,即使它不是最好的答案。你为什么要尝试一个更好的答案
回答一个没有被问到的问题?当然还有一个问题,这可能有用。这正是我想要的。我想不出如何更好地表达我的问题谢谢你,布伦特!这是我需要的答案,来自谷歌搜索Python3 convert str to bytes binary这是最好的结果,看起来很有希望。还有一些更有趣的问题,比如如何将unicode字符串转换为常规字符串python 2.7:p
s_new: bytes = bytes(s, encoding="raw_unicode_escape")