Mar*_*som 734 python string character-encoding python-3.x
似乎有两种不同的方法将字符串转换为字节,如TypeError的答案所示:'str'不支持缓冲区接口
哪种方法更好或更好Pythonic?或者只是个人喜好?
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
Run Code Online (Sandbox Code Playgroud)
agf*_*agf 517
如果您查看文档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,因为它是最自我的文档 - "使用此字符串并使用此编码对其进行编码"比bytes(some_string, encoding)
使用更清晰- 当您使用时没有明确的动词构造函数.
编辑:我检查了Python源代码.如果你将unicode字符串传递给bytes
使用CPython,它会调用PyUnicode_AsEncodedString,这是执行encode
; 所以如果你打电话给encode
自己,你只是跳过一个间接的水平.
另外,请参阅Serdalis的评论 - unicode_string.encode(encoding)
也更像Pythonic,因为它的反面byte_string.decode(encoding)
和对称性很好.
has*_*zmi 279
它比想象的容易:
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
Run Code Online (Sandbox Code Playgroud)
Ant*_*ala 107
在绝对最好的办法既不是2,但第3位.自Python 3.0以来默认的第一个参数.因此最好的方法是encode
'utf-8'
b = mystring.encode()
Run Code Online (Sandbox Code Playgroud)
这也会更快,因为默认参数不会"utf-8"
导致C代码中的字符串,但是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
Run Code Online (Sandbox Code Playgroud)
尽管有警告,但在重复运行后时间非常稳定 - 偏差仅为~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)
Run Code Online (Sandbox Code Playgroud)
Bre*_*ent 26
回答一个稍微不同的问题:
您有一个保存在 str 变量中的原始 unicode 序列:
s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"
Run Code Online (Sandbox Code Playgroud)
您需要能够获取该 unicode 的字节文字(对于 struct.unpack() 等)
s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'
Run Code Online (Sandbox Code Playgroud)
解决方案:
s_new: bytes = bytes(s, encoding="raw_unicode_escape")
Run Code Online (Sandbox Code Playgroud)
参考(向上滚动查看标准编码):
Python 3的“内存视图”方式怎么样?
Memoryview 是 byte/bytearray 和 struct 模块的一种混搭,有几个好处。
最简单的例子,对于字节数组:
memoryview(b"some bytes").tolist()
[115, 111, 109, 101, 32, 98, 121, 116, 101, 115]
Run Code Online (Sandbox Code Playgroud)
或者对于 unicode 字符串(转换为字节数组)
memoryview(bytes("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020", "UTF-16")).tolist()
[255, 254, 117, 0, 110, 0, 105, 0, 99, 0, 111, 0, 100, 0, 101, 0, 32, 0]
#Another way to do the same
memoryview("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020".encode("UTF-16")).tolist()
[255, 254, 117, 0, 110, 0, 105, 0, 99, 0, 111, 0, 100, 0, 101, 0, 32, 0]
Run Code Online (Sandbox Code Playgroud)
也许您需要的是单词而不是字节?
memoryview(bytes("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020", "UTF-16")).cast("H").tolist()
[65279, 117, 110, 105, 99, 111, 100, 101, 32]
memoryview(b"some more data").cast("L").tolist()
[1701670771, 1869422624, 538994034, 1635017060]
Run Code Online (Sandbox Code Playgroud)
小心的话。请注意对多于一个字节的数据的字节顺序的多种解释:
memoryview(bytes("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020", "UTF-16")).cast("H").tolist()
[65279, 117, 110, 105, 99, 111, 100, 101, 32]
memoryview(b"some more data").cast("L").tolist()
[1701670771, 1869422624, 538994034, 1635017060]
Run Code Online (Sandbox Code Playgroud)
不确定这是故意的还是错误,但它让我发现了!!
该示例使用 UTF-16,有关编解码器的完整列表,请参阅Python 3.10 中的编解码器注册表
归档时间: |
|
查看次数: |
1101035 次 |
最近记录: |