是否可以构造一个utf-8编解码器无法编码的unicode字符串?
Is it possible to construct a unicode string that the utf-8 codec cannot encode?
是否可以构造 utf-8
编解码器无法编码的 unicode 字符串?
从文档 (https://docs.python.org/2/library/codecs.html) 看来,utf-8
编解码器可以用“任何语言”对符号进行编码。文档还指出编解码器何时只能对某些字符或只能对基本多语言平面进行编码。但是,我不知道这是否等同于说“不可能构造一个无法使用 utf-8
编解码器转换为字节串的 unicode
值”。
这是 utf-8
编解码器的 table 条目。
Codec Aliases Purpose
utf_8 U8, UTF, utf8 all languages
这里的动机是我有一个实用函数,它接受 unicode 字符串或字节字符串并将其转换为字节字符串。当给定一个字节字符串时,它是一个空操作。这个函数不应该抛出异常,除非它是用非字符串类型调用的,在这种情况下,它应该会失败并带有稍后将被捕获并记录的 TypeError。 (如果我们试图插入到异常消息中的项目的 repr 太大,我们仍然可以 运行 遇到问题,但我们暂时忽略它)。
我正在使用 strict
设置,因为我希望此函数在遇到无法编码的 unicode 对象时抛出异常,但我希望这是不可能的。
def utf8_to_bytes(item):
"""take a bytes or unicode object and convert it to bytes,
using utf-8 if necessary"""
if isinstance(item, bytes):
return item
elif isinstance(item, unicode):
return codecs.encode(item, 'utf-8', 'strict')
else:
raise TypeError("item must be bytes or unicode. got %r" % type(item))
UTF-8 旨在对所有 Unicode 标准进行编码。将 Unicode 文本编码为 UTF-8 通常不会引发异常。
来自Wikipedia article on the codec:
UTF-8 is a character encoding capable of encoding all possible characters, or code points, defined by Unicode
Python2 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
模块,只需在 unicode
对象上使用 encode
方法即可:
return item.encode('utf-8')
在Python3中,情况稍微复杂一些。解码和编码surrogate pairs被限制;官方标准规定此类字符只应出现在 UTF-16 编码数据中,并且只能出现在低位和高位对中。
因此,您需要明确声明您希望使用 surrogatepass
error handler:
支持此类代码点
Allow encoding and decoding of surrogate codes. These codecs normally treat the presence of surrogates as an error.
surrogatepass
和 strict
之间的唯一区别是 surrogatepass
允许您将 Unicode 文本中的任何代理代码点编码为 UTF-8。您只会在极少数情况下获得此类数据(定义为文字,或者不小心将此类代码点在 UTF-16 中未配对,然后使用 surrogatepass
进行解码)。
因此,在 Python 3 中,仅当您有可能使用 surrogatepass
解码或从文字数据生成您的 Unicode 文本时,您需要使用 item.encode('utf8', 'surrogatepass')
才能绝对确定可以对所有可能的 Unicode 值进行编码。
是否可以构造 utf-8
编解码器无法编码的 unicode 字符串?
从文档 (https://docs.python.org/2/library/codecs.html) 看来,utf-8
编解码器可以用“任何语言”对符号进行编码。文档还指出编解码器何时只能对某些字符或只能对基本多语言平面进行编码。但是,我不知道这是否等同于说“不可能构造一个无法使用 utf-8
编解码器转换为字节串的 unicode
值”。
这是 utf-8
编解码器的 table 条目。
Codec Aliases Purpose
utf_8 U8, UTF, utf8 all languages
这里的动机是我有一个实用函数,它接受 unicode 字符串或字节字符串并将其转换为字节字符串。当给定一个字节字符串时,它是一个空操作。这个函数不应该抛出异常,除非它是用非字符串类型调用的,在这种情况下,它应该会失败并带有稍后将被捕获并记录的 TypeError。 (如果我们试图插入到异常消息中的项目的 repr 太大,我们仍然可以 运行 遇到问题,但我们暂时忽略它)。
我正在使用 strict
设置,因为我希望此函数在遇到无法编码的 unicode 对象时抛出异常,但我希望这是不可能的。
def utf8_to_bytes(item):
"""take a bytes or unicode object and convert it to bytes,
using utf-8 if necessary"""
if isinstance(item, bytes):
return item
elif isinstance(item, unicode):
return codecs.encode(item, 'utf-8', 'strict')
else:
raise TypeError("item must be bytes or unicode. got %r" % type(item))
UTF-8 旨在对所有 Unicode 标准进行编码。将 Unicode 文本编码为 UTF-8 通常不会引发异常。
来自Wikipedia article on the codec:
UTF-8 is a character encoding capable of encoding all possible characters, or code points, defined by Unicode
Python2 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
模块,只需在 unicode
对象上使用 encode
方法即可:
return item.encode('utf-8')
在Python3中,情况稍微复杂一些。解码和编码surrogate pairs被限制;官方标准规定此类字符只应出现在 UTF-16 编码数据中,并且只能出现在低位和高位对中。
因此,您需要明确声明您希望使用 surrogatepass
error handler:
Allow encoding and decoding of surrogate codes. These codecs normally treat the presence of surrogates as an error.
surrogatepass
和 strict
之间的唯一区别是 surrogatepass
允许您将 Unicode 文本中的任何代理代码点编码为 UTF-8。您只会在极少数情况下获得此类数据(定义为文字,或者不小心将此类代码点在 UTF-16 中未配对,然后使用 surrogatepass
进行解码)。
因此,在 Python 3 中,仅当您有可能使用 surrogatepass
解码或从文字数据生成您的 Unicode 文本时,您需要使用 item.encode('utf8', 'surrogatepass')
才能绝对确定可以对所有可能的 Unicode 值进行编码。