在Python3中将字符串转换为字节的最佳方法?
将字符串转换为字节似乎有两种不同的方法,如 这些方法中哪一种更好或更具Pythonic?还是只是个人喜好的问题在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([source[,encoding[,errors]])) 返回一个新的字节数组。bytearray类型是一个范围为0的可变整数序列,比想象的要简单: my_str = "hello world" my_str_a
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
如果查看文档中的
字节
,它会指向:
bytearray([source[,encoding[,errors]]))
返回一个新的字节数组。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
>>“äöä”.encode()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
UnicodeDecodeError:“ascii”编解码器无法解码位置0中的字节0xc3:序号不在范围内(128)
回答稍微不同的问题:
您有一个原始unicode序列,该序列已保存到str变量中:
s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"
您需要能够获取该unicode的字节文字(对于struct.unpack()等)
解决方案:
s_new: bytes = bytes(s, encoding="raw_unicode_escape")
参考(向上滚动以获取标准编码):
+1,感谢您从python文档中获得了一个好的参数和引用。另外,当您想要回字符串时,
unicode\u string.encode(encoding)
与bytearray.decode(encoding)
非常匹配。bytearray
在您需要可变对象时使用。对于简单的str
↔<代码>字节转换。@EugeneHomyakov这与bytearray
无关,只是字节
的文档没有给出详细信息,他们只是说“这是bytearray
的不可变版本”,所以我不得不引用其中的内容。注意,如果您试图将二进制数据转换为字符串,您很可能需要使用类似于byte\u string.decode('latin-1')
的东西,因为utf-8
没有覆盖整个范围0x00到0xFF(0-255),请查看python以了解更多信息。tl;dr
会很有帮助,因为编码/解码更常见,而且可能更清晰。@Lennartreegebro我不这么认为。即使读“bytes()”更常见,但我知道它在做什么,而encode()并不会让我觉得它是在编码字节。@erm3nda这是使用它的一个很好的理由,直到它真的这样做,那么你离Unicode zen更近了一步。@LennartRegebro我觉得只要使用字节(项,“utf8”)
,因为显式比隐式好,所以str.encode()
默认默认为字节,这使您的zen更为Unicode,但不那么明确。“普通”这个词我也不喜欢用。另外,字节(项目“utf8”)
,更像str()
,和b“string”
符号。如果我无法理解你的理由,我深表歉意。谢谢。@erm3nda如果您阅读了接受的答案,您会发现encode()
不会调用bytes()
,相反。当然,这不是很明显,这就是为什么我问这个问题。他知道怎么做,他只是问哪种方式更好。请重新阅读问题。仅供参考:str.decode(字节)对我不起作用(Python 3.3.3说“type object'str'没有'decode'属性”),我使用了bytes.decode()instead@Mike:使用obj.method()
语法而不是cls.method(obj)
语法,即使用bytestring=unicode\u text.encode(编码)
和unicode\u text=bytestring.decode(编码)
。。。。i、 e.您不必要地创建了一个未绑定的方法,然后将self
作为第一个调用它argument@KolobCanyon这个问题已经显示了正确的方法,即调用encode
作为字符串上的绑定方法。这个答案建议您应该调用unbound方法并将字符串传递给它。这是答案中唯一的新信息,这是错误的。这里只有一个很大的区别,因为(a)字符串是纯ASCII,这意味着内部存储已经是UTF-8版本,因此查找编解码器几乎是所有涉及的唯一成本,(b)字符串很小,因此即使您必须编码,这没什么区别。试试看,比如说,'\u00012345'*10000
。两者都可以在我的笔记本电脑上占用28.8us;额外的50纳秒可能在舍入误差中丢失。当然,这是一个非常极端的例子,但在相反的方向上,'abc'
也同样极端。@abarnert-true,但即使如此,也没有理由将参数作为字符串传递。根据这一点,默认参数始终是“绝对最好的方式”来做事情,对吗?如果这是关于讨论C代码的话,这种速度分析可能会觉得有些夸张。在解释语言中,这让我哑口无言。如果你显式地键入默认参数值,你将一无所获——击键次数越多,代码越大,速度也越慢。Python的Zen声明显式优于隐式,这意味着显式'utf-8'
参数是首选参数。但您已经明确表明,去掉参数更快。这就是一个很好的答案,即使它不是最好的答案。你为什么要回答一个没有被问到的问题?当然还有一个问题,这可能有用。这正是我想要的。我想不出如何更好地表达我的问题谢谢你,布伦特!这就是我需要的答案,来自谷歌搜索“Python3将str转换为字节”
s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'
s_new: bytes = bytes(s, encoding="raw_unicode_escape")