UTF-8 旨在对所有 Unicode 标准进行编码。将 Unicode 文本编码为 UTF-8 通常不会引发异常。
来自关于编解码器的维基百科文章 https://en.wikipedia.org/wiki/UTF-8:
UTF-8 是一种字符编码,能够对 Unicode 定义的所有可能的字符或代码点进行编码
据我所知,Python 2 UTF-8 编码没有边缘情况;非 BMP 数据和代理对的处理方式相同:
>>> import sys
>>> hex(sys.maxunicode) # a narrow UCS-2 build
'0xffff'
>>> len(u'\U0001F525')
2
>>> u'\U0001F525'.encode('utf-8')
'\xf0\x9f\x94\xa5'
>>> u'\ud83d\udd25'
u'\U0001f525'
>>> len(u'\ud83d\udd25')
2
>>> u'\ud83d\udd25'.encode('utf-8')
'\xf0\x9f\x94\xa5'
注意strict
是默认的编码模式。您不需要使用codecs
模块也可以,只需使用encode
方法上的unicode
object:
return item.encode('utf-8')
在Python 3中,情况稍微复杂一些。解码和编码代理对 https://en.wikipedia.org/wiki/UTF-16#U.2BD800_to_U.2BDFFF受到限制;官方标准规定此类字符只能出现在 UTF-16 编码数据中,并且只能出现在低位和高位对中。
因此,您需要明确声明您希望支持此类代码点surrogatepass错误处理程序 https://docs.python.org/3/library/codecs.html#error-handlers:
允许代理代码的编码和解码。这些编解码器通常将代理的存在视为错误。
之间唯一的区别surrogatepass
and strict
就是它surrogatepass
将允许您将 Unicode 文本中的任何代理代码点编码为 UTF-8。您只会在极少数情况下获得此类数据(定义为文字,或者意外地将此类代码点保留在 UTF-16 中不配对,然后使用surrogatepass
).
所以,在 Python 3 中,仅当您有机会使用 Unicode 文本生成时surrogatepass
解码或从文字数据,你需要使用item.encode('utf8', 'surrogatepass')
绝对确定所有可能的 Unicode 值都可以被编码。