Skip to main content

7.2. codecs —编解码器注册表和基类

源代码: Lib/codecs.py


该模块为标准Python编解码器(编码器和解码器)定义基类,并提供对内部Python编解码器注册表的访问,该注册表管理编解码器和错误处理查找过程。大多数标准编解码器是 文本编码,它将文本编码为字节,但也提供编码器将文本编码为文本,字节编码为字节。定制编解码器可以在任意类型之间编码和解码,但是某些模块特征被限制为专门用于 文本编码 或者编码到 bytes 的编解码器。

模块定义以下用于使用任何编解码器进行编码和解码的功能:

codecs.encode(obj, encoding='utf-8', errors='strict')

使用为 encoding 注册的编解码器对 obj 进行编码。

可以给予 Errors 以设置期望的错误处理方案。默认错误处理程序是 'strict',意味着编码错误引起 ValueError (或更多编解码器特定的子类,例如 UnicodeEncodeError)。有关编解码器错误处理的更多信息,请参阅 编解码器基类

codecs.decode(obj, encoding='utf-8', errors='strict')

使用为 encoding 注册的编解码器解码 obj

可以给予 Errors 以设置期望的错误处理方案。默认错误处理程序是 'strict',意味着解码错误提高 ValueError (或更多编解码器特定的子类,例如 UnicodeDecodeError)。有关编解码器错误处理的更多信息,请参阅 编解码器基类

每个编解码器的完整详细信息也可以直接查找:

codecs.lookup(encoding)

在Python编解码器注册表中查找编解码器信息,并返回如下定义的 CodecInfo 对象。

首先在注册表的缓存中查找编码。如果未找到,则会扫描注册的搜索功能列表。如果没有找到 CodecInfo 对象,则引发 LookupError。否则,CodecInfo 对象存储在缓存中并返回给调用者。

class codecs.CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None)

查找编解码器注册表时的编解码器详细信息。构造函数参数存储在同名的属性中:

name

编码的名称。

encode
decode

无状态编码和解码功能。这些必须是具有与编解码器实例的 encode()decode() 方法相同的接口的函数或方法(参见 编解码器接口)。这些函数或方法应该在无状态模式下工作。

incrementalencoder
incrementaldecoder

增量编码器和解码器类或工厂功能。这些必须分别提供由基类 IncrementalEncoderIncrementalDecoder 定义的接口。增量编解码器可以维护状态。

streamwriter
streamreader

流写入器和读取器类或工厂函数。这些必须分别提供由基类 StreamWriterStreamReader 定义的接口。流编解码器可以维护状态。

为了简化对各种编解码器组件的访问,模块提供了使用 lookup() 进行编解码器查找的这些附加功能:

codecs.getencoder(encoding)

查找给定编码的编解码器并返回其编码器函数。

在无法找到编码的情况下提升 LookupError

codecs.getdecoder(encoding)

查找给定编码的编解码器并返回其解码器功能。

在无法找到编码的情况下提升 LookupError

codecs.getincrementalencoder(encoding)

查找给定编码的编解码器,并返回其增量编码器类或工厂函数。

在无法找到编码或编解码器不支持增量编码器的情况下提升 LookupError

codecs.getincrementaldecoder(encoding)

查找给定编码的编解码器,并返回其增量解码器类或工厂函数。

在无法找到编码或编解码器不支持增量解码器的情况下提升 LookupError

codecs.getreader(encoding)

查找给定编码的编解码器并返回其 StreamReader 类或工厂函数。

在无法找到编码的情况下提升 LookupError

codecs.getwriter(encoding)

查找给定编码的编解码器并返回其 StreamWriter 类或工厂函数。

在无法找到编码的情况下提升 LookupError

通过注册合适的编解码器搜索功能,可以使用自定义编解码器:

codecs.register(search_function)

注册编解码器搜索功能。搜索函数需要一个参数,即所有小写字母的编码名称,并返回一个 CodecInfo 对象。如果搜索功能找不到给定的编码,它应该返回 None

注解

搜索功能注册当前不可逆,这在某些情况下可能会导致问题,例如单元测试或模块重新加载。

虽然内置 open() 和关联的 io 模块是处理编码文本文件的推荐方法,但此模块提供了其他实用程序函数和类,以允许在使用二进制文件时使用更广泛的编解码器:

codecs.open(filename, mode='r', encoding=None, errors='strict', buffering=1)

使用给定的 mode 打开编码文件,并返回 StreamReaderWriter 的实例,提供透明编码/解码。默认文件模式为 'r',意味着在读取模式下打开文件。

注解

底层编码文件始终以二进制模式打开。在读取和写入时不进行 '\n' 的自动转换。 mode 参数可以是内置 open() 功能可接受的任何二进制模式; 'b' 会自动添加。

encoding 指定要用于文件的编码。允许对字节进行编码和解码的任何编码,文件方法支持的数据类型取决于所使用的编解码器。

可以给出 errors 来定义错误处理。它默认为 'strict',这导致在编码错误发生的情况下产生 ValueError

buffering 具有与内置 open() 函数相同的含义。它默认为行缓冲。

codecs.EncodedFile(file, data_encoding, file_encoding=None, errors='strict')

返回 StreamRecoder 实例,file 的封装版本,提供透明转码。关闭封装版本时,将关闭原始文件。

写入包装文件的数据根据给定的 data_encoding 进行解码,然后使用 file_encoding 作为字节写入原始文件。从原始文件读取的字节根据 file_encoding 解码,并且使用 data_encoding 对结果进行编码。

如果没有给出 file_encoding,它默认为 data_encoding

可以给出 errors 来定义错误处理。它默认为 'strict',这导致在发生编码错误的情况下 ValueError 被升高。

codecs.iterencode(iterator, encoding, errors='strict', **kwargs)

使用增量编码器对 iterator 提供的输入进行迭代编码。这个功能是 generatorerrors 参数(以及任何其他关键字参数)传递到增量编码器。

此函数要求编解码器接受要编码的文本 str 对象。因此,它不支持诸如 base64_codec 的字节到字节编码器。

codecs.iterdecode(iterator, encoding, errors='strict', **kwargs)

使用增量解码器迭代解码 iterator 提供的输入。这个功能是 generatorerrors 参数(以及任何其他关键字参数)传递到增量解码器。

此功能要求编解码器接受 bytes 对象进行解码。因此,它不支持文本到文本编码器,例如 rot_13,尽管 rot_13 可以与 iterencode() 等价使用。

该模块还提供以下常数,用于读取和写入平台相关文件:

codecs.BOM
codecs.BOM_BE
codecs.BOM_LE
codecs.BOM_UTF8
codecs.BOM_UTF16
codecs.BOM_UTF16_BE
codecs.BOM_UTF16_LE
codecs.BOM_UTF32
codecs.BOM_UTF32_BE
codecs.BOM_UTF32_LE

这些常量定义了各种字节序列,是几个编码的Unicode字节顺序标记(BOM)。它们在UTF-16和UTF-32数据流中使用,以指示使用的字节顺序,并且在UTF-8中用作Unicode签名。 BOM_UTF16BOM_UTF16_BEBOM_UTF16_LE,取决于平台的本地字节顺序,BOMBOM_UTF16 的别名,BOM_UTF16_LEBOM_LEBOM_UTF16_BEBOM_BE。其他代表UTF-8和UTF-32编码的BOM。

7.2.1. 编解码器基类

codecs 模块定义了一组基本类,它们定义了使用编解码器对象的接口,也可以用作自定义编解码器实现的基础。

每个编解码器必须定义四个接口,使其可用作Python中的编解码器:无状态编码器,无状态解码器,流读取器和流写入器。流读取器和写入器通常重用无状态编码器/解码器来实现文件协议。编解码器作者还需要定义编解码器将如何处理编码和解码错误。

7.2.1.1. 错误处理程序

为了简化和标准化错误处理,编解码器可以通过接受 errors 字符串参数来实现不同的错误处理方案。以下字符串值由所有标准Python编解码器定义和实现:

含义

'strict'

提高 UnicodeError (或子类);这是默认值。在 strict_errors() 中实施。

'ignore'

忽略格式错误的数据,并继续操作,无需另行通知。在 ignore_errors() 中实现。

以下错误处理程序仅适用于 文本编码

含义

'replace'

更换合适的替换标记; Python将使用官方的 U+FFFD REPLACEMENT CHARACTER来解码内置编解码器,而’?’关于编码。在 replace_errors() 中实施。

'xmlcharrefreplace'

替换为适当的XML字符引用(仅用于编码)。在 xmlcharrefreplace_errors() 中实现。

'backslashreplace'

用反斜杠转义序列替换。在 backslashreplace_errors() 中实现。

'namereplace'

\N{...} 转义序列替换(仅用于编码)。在 namereplace_errors() 中实施。

'surrogateescape'

在解码时,将字节替换为范围从 U+DC80U+DCFF 的各个代理码。当编码数据时使用 'surrogateescape' 错误处理程序时,此代码将被转回到同一字节。 (更多信息,请参见 PEP 383。)

此外,以下错误处理程序特定于给定的编解码器:

编解码器

含义

'surrogatepass'

utf-8,utf-16,utf-32,utf-16-be,utf-16-le,utf-32-be,utf-

允许代理代码的编码和解码。这些编解码器通常将代理的存在视为错误。

3.1 新版功能: 'surrogateescape''surrogatepass' 错误处理程序。

在 3.4 版更改: 'surrogatepass' 错误处理程序现在可以与utf-16*和utf-32*编解码器一起使用。

3.5 新版功能: 'namereplace' 错误处理程序。

在 3.5 版更改: 'backslashreplace' 错误处理程序现在可以解码和翻译。

可以通过注册一个新的命名错误处理程序来扩展允许的值集合:

codecs.register_error(name, error_handler)

以名称 name 注册错误处理函数 error_handler。在 name 被指定为errors参数的情况下,在编码和解码期间将调用 error_handler 参数,以防出现错误。

对于编码,将使用 UnicodeEncodeError 实例调用 error_handler,该实例包含有关错误位置的信息。错误处理程序必须提出这个或不同的异常,或者返回一个替换为输入的不可编辑部分的元组以及编码应该继续的位置。替换可以是 strbytes。如果替换是字节,则编码器将它们简单地复制到输出缓冲器中。如果替换是字符串,则编码器将对替换进行编码。在指定位置的原始输入上继续编码。负位置值将被视为相对于输入字符串的结尾。如果结果位置超出界限,则将产生 IndexError

解码和转换工作类似,除了 UnicodeDecodeErrorUnicodeTranslateError 将被传递到处理程序,并且从错误处理程序的替换将直接放入输出。

以前注册的错误处理程序(包括标准错误处理程序)可以按名称查找:

codecs.lookup_error(name)

返回以前以名称 name 注册的错误处理程序。

在无法找到处理程序的情况下引发 LookupError

以下标准错误处理程序也可用作模块级函数:

codecs.strict_errors(exception)

实现 'strict' 错误处理:每个编码或解码错误产生一个 UnicodeError

codecs.replace_errors(exception)

实现 'replace' 错误处理(仅适用于 文本编码):用 '?' 替换编码错误(由编解码器编码),用 '\ufffd' (Unicode替换字符)替换解码错误。

codecs.ignore_errors(exception)

实现 'ignore' 错误处理:忽略格式错误的数据,并继续编码或解码,无需另行通知。

codecs.xmlcharrefreplace_errors(exception)

实现 'xmlcharrefreplace' 错误处理(仅适用于 文本编码 编码):不可编码字符由适当的XML字符引用替换。

codecs.backslashreplace_errors(exception)

实现 'backslashreplace' 错误处理(仅适用于 文本编码):格式错误的数据由反斜杠转义序列替换。

codecs.namereplace_errors(exception)

实现 'namereplace' 错误处理(仅用于 文本编码 编码):不可编码字符由 \N{...} 转义序列替换。

3.5 新版功能.

7.2.1.2. 无状态编码和解码

基本 Codec 类定义了这些方法,它们还定义了无状态编码器和解码器的功能接口:

Codec.encode(input[, errors])

对对象 input 进行编码,并返回一个元组(输出对象,消耗的长度)。例如,text encoding 使用特定字符集编码(例如,cp1252iso-8859-1)将字符串对象转换为字节对象。

errors 参数定义要应用的错误处理。它默认为 'strict' 处理。

该方法可以不在 Codec 实例中存储状态。使用 StreamWriter 编解码器,必须保持状态,以使编码效率。

在这种情况下,编码器必须能够处理零长度输入并返回输出对象类型的空对象。

Codec.decode(input[, errors])

解码对象 input 并返回一个元组(输出对象,消耗的长度)。例如,对于 text encoding,解码将使用特定字符集编码编码的字节对象转换为字符串对象。

对于文本编码和字节到字节编解码器,input 必须是字节对象或提供只读缓冲区接口的对象,例如缓冲区对象和内存映射文件。

errors 参数定义要应用的错误处理。它默认为 'strict' 处理。

该方法可以不在 Codec 实例中存储状态。对于必须保持状态以便使解码有效的编解码器使用 StreamReader

在这种情况下,解码器必须能够处理零长度输入并返回输出对象类型的空对象。

7.2.1.3. 增量编码和解码

IncrementalEncoderIncrementalDecoder 类提供增量编码和解码的基本接口。不通过对无状态编码器/解码器功能的一次调用而是通过对增量编码器/解码器的 encode()/decode() 方法的多次调用来完成对输入的编码/解码。增量编码器/解码器在方法调用期间跟踪编码/解码过程。

encode()/decode() 方法的调用的联合输出与所有单个输入被合并成一个输入相同,并且该输入用无状态编码器/解码器编码/解码。

7.2.1.3.1. IncrementalEncoder对象

IncrementalEncoder 类用于在多个步骤中对输入进行编码。它定义了以下方法,每个增量编码器必须定义以与Python编解码器注册表兼容。

class codecs.IncrementalEncoder(errors='strict')

IncrementalEncoder 实例的构造方法。

所有增量编码器必须提供此构造函数接口。他们可以自由添加额外的关键字参数,但只有这里定义的参数被Python编解码器注册表使用。

IncrementalEncoder 可以通过提供 errors 关键字参数来实现不同的错误处理方案。有关可能的值,请参阅 错误处理程序

errors 参数将分配给同名的属性。分配到此属性使得可以在 IncrementalEncoder 对象的生存期内在不同的错误处理策略之间切换。

encode(object[, final])

编码 object (考虑编码器的当前状态),并返回生成的编码对象。如果这是最后一次调用 encode(),则 final 必须为true(默认值为false)。

reset()

将编码器重置为初始状态。输出被丢弃:调用 .encode(object, final=True),如果必要,传递空字节或文本字符串,以重置编码器并获得输出。

IncrementalEncoder.getstate()

返回编码器的当前状态,必须为整数。实施应确保 0 是最常见的状态。 (比整数更复杂的状态可以通过编组/选择状态并将结果字符串的字节编码为整数来转换为整数)。

IncrementalEncoder.setstate(state)

将编码器的状态设置为 statestate 必须是 getstate() 返回的编码器状态。

7.2.1.3.2. IncrementalDecoder对象

IncrementalDecoder 类用于以多个步骤对输入进行解码。它定义以下方法,每个增量解码器必须定义以便与Python编解码器注册表兼容。

class codecs.IncrementalDecoder(errors='strict')

IncrementalDecoder 实例的构造方法。

所有增量解码器必须提供此构造函数接口。他们可以自由添加额外的关键字参数,但只有这里定义的参数被Python编解码器注册表使用。

IncrementalDecoder 可以通过提供 errors 关键字参数来实现不同的错误处理方案。有关可能的值,请参阅 错误处理程序

errors 参数将分配给同名的属性。分配到此属性使得可以在 IncrementalDecoder 对象的生存期内在不同的错误处理策略之间切换。

decode(object[, final])

解码 object (考虑解码器的当前状态),并返回结果解码的对象。如果这是最后一次调用 decode(),则 final 必须为true(默认值为false)。如果 final 为真,则解码器必须完全解码输入并且必须刷新所有缓冲器。如果这是不可能的(例如,由于在输入结束处的不完整的字节序列),它必须像在无状态情况下那样启动错误处理(这可能引起异常)。

reset()

将解码器重置为初始状态。

getstate()

返回解码器的当前状态。这必须是一个有两个项的元组,第一个必须是包含静态未解码输入的缓冲区。第二个必须是整数,并且可以是附加的状态信息。 (实现应该确保 0 是最常见的附加状态信息)。如果这个附加状态信息是 0,则必须能够将解码器设置为没有输入缓冲的状态,并且 0 作为附加状态信息,使得将先前缓冲的输入馈送到解码器使其返回到先前状态而不产生任何输出。 (通过编组/选择信息并将结果字符串的字节编码为整数,可以将比整数更复杂的附加状态信息转换为整数。)

setstate(state)

将编码器的状态设置为 statestate 必须是 getstate() 返回的解码器状态。

7.2.1.4. 流编码和解码

StreamWriterStreamReader 类提供通用的工作接口,可以非常容易地用于实现新的编码子模块。有关如何完成此操作的示例,请参阅 encodings.utf_8

7.2.1.4.1. StreamWriter对象

StreamWriter 类是 Codec 的子类,并定义以下方法,每个流写入器必须定义以便与Python编解码器注册表兼容。

class codecs.StreamWriter(stream, errors='strict')

StreamWriter 实例的构造方法。

所有流编写器必须提供此构造函数接口。他们可以自由添加额外的关键字参数,但只有这里定义的参数被Python编解码器注册表使用。

stream 参数必须是用于写入文本或二进制数据的类文件对象,适用于特定编解码器。

StreamWriter 可以通过提供 errors 关键字参数来实现不同的错误处理方案。有关基本流编解码器可能支持的标准错误处理程序,请参阅 错误处理程序

errors 参数将分配给同名的属性。分配到此属性使得可以在 StreamWriter 对象的生存期内在不同的错误处理策略之间切换。

write(object)

将编码的对象的内容写入流。

writelines(list)

将串联的字符串列表写入流(可能通过重用 write() 方法)。标准字节到字节编解码器不支持此方法。

reset()

刷新并重置用于保持状态的编解码器缓冲区。

调用此方法应该确保输出上的数据被置于一个干净的状态,允许附加新的新数据,而不必重新扫描整个流恢复状态。

除了上述方法之外,StreamWriter 还必须从底层流继承所有其他方法和属性。

7.2.1.4.2. StreamReader对象

StreamReader 类是 Codec 的子类,并定义以下方法,每个流读取器必须定义以便与Python编解码器注册表兼容。

class codecs.StreamReader(stream, errors='strict')

StreamReader 实例的构造方法。

所有流读取器必须提供此构造函数接口。他们可以自由添加额外的关键字参数,但只有这里定义的参数被Python编解码器注册表使用。

stream 参数必须是一个类文件对象,用于读取文本或二进制数据,适用于特定的编解码器。

StreamReader 可以通过提供 errors 关键字参数来实现不同的错误处理方案。有关基本流编解码器可能支持的标准错误处理程序,请参阅 错误处理程序

errors 参数将分配给同名的属性。分配到此属性使得可以在 StreamReader 对象的生存期内在不同的错误处理策略之间切换。

errors 参数的允许值集合可以使用 register_error() 扩展。

read([size[, chars[, firstline]]])

解码来自流的数据,并返回结果对象。

chars 参数指示要返回的解码代码点或字节的数量。 read() 方法永远不会返回比请求的更多的数据,但如果没有足够的可用,它可能返回更少。

size 参数指示用于解码读取的编码字节或代码点的大致最大数目。解码器可以适当地修改此设置。默认值-1表示尽可能多地读取和解码。此参数旨在防止必须在一个步骤中解码巨大的文件。

firstline 标志指示如果在后面的行上存在解码错误,则仅返回第一行就足够了。

该方法应该使用贪婪读取策略,意味着它应该读取与编码和给定大小的定义内允许的数据一样多的数据,例如。如果可选的编码结束或状态标记在流上可用,这些应该也读。

readline([size[, keepends]])

从输入流中读取一行并返回解码后的数据。

size,如果给定,作为size参数传递到流的 read() 方法。

如果 keepends 为假,则将从返回的行中去除行末尾。

readlines([sizehint[, keepends]])

读取输入流上的所有可用行,并将它们作为行的列表返回。

行结束使用编解码器的解码器方法实现,如果 keepends 为真,则包含在列表条目中。

如果给定 sizehint,则将其作为 size 参数传递到流的 read() 方法。

reset()

重置用于保持状态的编解码器缓冲区。

注意,不应进行流重新定位。该方法主要旨在能够从解码错误中恢复。

除了上述方法之外,StreamReader 还必须从底层流继承所有其他方法和属性。

7.2.1.4.3. StreamReaderWriter对象

StreamReaderWriter 是一个方便的类,允许包装流工作在读和写模式。

设计是这样的,可以使用 lookup() 函数返回的工厂函数来构造实例。

class codecs.StreamReaderWriter(stream, Reader, Writer, errors)

创建 StreamReaderWriter 实例。 stream 必须是类似文件的对象。 ReaderWriter 必须是提供 StreamReaderStreamWriter 接口的工厂功能或类。错误处理以与为流读取器和写入程序定义的相同的方式完成。

StreamReaderWriter 实例定义 StreamReaderStreamWriter 类的组合接口。它们从底层流继承所有其他方法和属性。

7.2.1.4.4. StreamRecoder对象

StreamRecoder 将数据从一个编码转换到另一个,这在处理不同编码环境时有时是有用的。

设计是这样的,可以使用 lookup() 函数返回的工厂函数来构造实例。

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)

创建实现双向转换的 StreamRecoder 实例:encodedecode 在前端工作 - 代码调用 read()write() 的数据可见,而 ReaderWriter 在后端工作 - stream 中的数据。

您可以使用这些对象进行透明转码,例如拉丁语-1到UTF-8和回。

stream 参数必须是类文件对象。

encodedecode 参数必须遵守 Codec 接口。 ReaderWriter 必须是分别提供 StreamReaderStreamWriter 接口的对象的工厂功能或类。

错误处理以与为流读取器和写入程序定义的相同的方式完成。

StreamRecoder 实例定义 StreamReaderStreamWriter 类的组合接口。它们从底层流继承所有其他方法和属性。

7.2.2. 编码和Unicode

字符串在内部存储为范围 0x0-0x10FFFF 中的代码点序列。 (有关实现的更多细节,请参阅 PEP 393。)一旦字符串对象在CPU和内存之外使用,字节序以及这些数组如何作为字节存储就成为一个问题。与其他编解码器一样,将字符串序列化为字节序列被称为 encoding,并且从字节序列重新创建字符串被称为 decoding。有各种不同的文本串行编解码器,它们是集合性称为 文本编码

最简单的文本编码(称为 'latin-1''iso-8859-1')将代码点0–255映射到字节 0x0-0xff,这意味着包含 U+00FF 之上的代码点的字符串对象不能用该编解码器编码。这样做会产生类似以下内容的 UnicodeEncodeError (虽然错误消息的详细信息可能不同):UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256)

还有另一组编码(所谓的charmap编码)选择所有Unicode代码点的不同子集,以及这些代码点如何映射到字节 0x0 - 0xff。要了解如何完成此操作,只需打开例如 encodings/cp1252.py (这是主要在Windows上使用的编码)。有一个256个字符的字符串常量,显示哪个字符映射到哪个字节值。

所有这些编码只能编码Unicode中定义的1114112个代码点中的256个。可以存储每个Unicode代码点的简单和直接的方法是将每个代码点存储为四个连续字节。有两种可能性:以大端序或小端序的顺序存储字节。这两种编码分别称为 UTF-32-BEUTF-32-LE。它们的缺点是,你在一个小端机上使用 UTF-32-BE,你总是必须交换字节编码和解码。 UTF-32 避免了这个问题:字节将始终是自然的字节序。当这些字节被具有不同字节顺序的CPU读取时,字节必须交换。为了能够检测 UTF-16UTF-32 字节序列的字节顺序,有所谓的BOM(“字节顺序标记”)。这是Unicode字符 U+FEFF。此字符可以预置到每个 UTF-16UTF-32 字节序列。该字符的字节交换版本(0xFFFE)是可能不会出现在Unicode文本中的非法字符。因此,当 UTF-16UTF-32 字节序列中的第一个字符显示为 U+FFFE 时,必须在解码时交换字节。不幸的是,字符 U+FEFF 有第二个目的作为一个 ZERO WIDTH NO-BREAK SPACE:一个字符没有宽度,不允许单词分裂。它可以例如。用于给连字算法提示。使用 U+FEFF 作为 ZERO WIDTH NO-BREAK SPACE 的Unicode 4.0已被弃用(使用 U+2060WORD JOINER)承担这个角色)。然而,Unicode软件仍然必须能够在两种角色中处理 U+FEFF:作为BOM,它是确定编码字节的存储布局的设备,并且一旦字节序列被解码为字符串就消失;作为一个 ZERO WIDTH NO-BREAK SPACE 它是一个正常的字符,将像任何其他解码。

还有另一种编码能够对Unicode字符的所有范围进行编码:UTF-8。 UTF-8是一个8位编码,这意味着在UTF-8中没有字节顺序的问题。 UTF-8字节序列中的每个字节由两部分组成:标记位(最高有效位)和有效载荷位。标记位是零到四个 1 位的序列,后跟 0 位。 Unicode字符是这样编码的(x是有效载荷位,当连接时为Unicode字符):

范围

编码

U-00000000 ... U-0000007F

0xxxxxxx

U-00000080 ... U-000007FF

110xxxxx 10xxxxxx

U-00000800 ... U-0000FFFF

1110xxxx 10xxxxxx 10xxxxxx

U-00010000 ... U-0010FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Unicode字符的最低有效位是最右边的x位。

由于UTF-8是8位编码,因此不需要BOM,解码字符串中的任何 U+FEFF 字符(即使它是第一个字符)都被视为 ZERO WIDTH NO-BREAK SPACE

没有外部信息,不可能可靠地确定哪个编码用于编码字符串。每个charmap编码可以解码任何随机字节序列。然而,这不可能与UTF-8,因为UTF-8字节序列具有不允许任意字节序列的结构。为了提高可以检测UTF-8编码的可靠性,微软发明了一个UTF-8变体(Python 2.5调用 "utf-8-sig"),用于其记事本程序:在任何Unicode字符写入文件之前,一个UTF- 8编码的BOM(其看起来像字节序列:0xef0xbb0xbf)。因为任何charmap编码文件都是以这些字节值开始的(例如映射到)是不太可能的

拉丁小写我与DIAERESIS
正确的双角报价标记
被问及的问题

在iso-8859-1中),这增加了可以从字节序列正确猜测 utf-8-sig 编码的概率。所以这里BOM不能用于确定用于生成字节序列的字节顺序,而是用作有助于猜测编码的签名。在编码时,utf-8-sig编解码器将把 0xef0xbb0xbf 作为前三个字节写入文件。在解码时,utf-8-sig 将跳过这三个字节,如果它们作为文件中的前三个字节出现。在UTF-8中,不建议使用BOM,一般应避免使用。

7.2.3. 标准编码

Python附带了许多内置的编解码器,实现为C函数或者作为映射表的字典。下表按名称列出编解码器,以及几个常用别名以及可能使用编码的语言。无论是别名列表还是语言列表都不是详尽无遗的。请注意,只有不同的情况或使用连字符而不是下划线的拼写备选方案也是有效的别名;因此,例如。 'utf-8''utf_8' 编解码器的有效别名。

一些常见的编码可以绕过编解码器查找机制以提高性能。这些优化机会只能由CPython识别一组有限的别名:utf-8,utf8,latin-1,latin1,iso-8859-1,mbcs(仅限Windows),ascii,utf-16和utf-32。对这些编码使用替代拼写可能会导致执行速度较慢。

许多字符集支持相同的语言。它们以单个字符(例如,是否支持EURO SIGN)以及字符到代码位置的分配而变化。尤其对于欧洲语言,通常存在以下变体:

  • ISO 8859代码集

  • Microsoft Windows代码页,通常派生自8859代码集,但用附加的图形字符替换控制字符

  • IBM EBCDIC代码页

  • 一个IBM PC代码页,它是ASCII兼容的

编解码器

别名

语言

ascii

646,us-ascii

英语

big5

big5-tw,csbig5

繁体中文

big5hkscs

big5-hkscs,hkscs

繁体中文

cp037

IBM037,IBM039

英语

cp273

273,IBM273,csIBM273

德语

3.4 新版功能.

cp424

EBCDIC-CP-HE,IBM424

希伯来语

cp437

437,IBM437

英语

cp500

EBCDIC-CP-BE,EBCDIC-CP-CH,IBM500

西欧

cp720

 

阿拉伯

cp737

 

希腊语

cp775

IBM775

波罗的海语言

cp850

850,IBM850

西欧

cp852

852,IBM852

中欧和东欧

cp855

855,IBM855

保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语

cp856

 

希伯来语

cp857

857,IBM857

土耳其

cp858

858,IBM858

西欧

cp860

860,IBM860

葡萄牙语

cp861

861,CP-IS,IBM861

冰岛的

cp862

862,IBM862

希伯来语

cp863

863,IBM863

加拿大

cp864

IBM864

阿拉伯

cp865

865,IBM865

丹麦语,挪威语

cp866

866,IBM866

俄语

cp869

869,CP-GR,IBM869

希腊语

cp874

 

泰国

cp875

 

希腊语

cp932

932,ms932,mskanji,ms-kanji

日本

cp949

949,ms949,uhc

韩语

cp950

950,ms950

繁体中文

cp1006

 

乌尔都语

cp1026

ibm1026

土耳其

cp1125

1125,ibm1125,cp866u,ruscii

乌克兰

3.4 新版功能.

cp1140

ibm1140

西欧

cp1250

windows-1250

中欧和东欧

cp1251

windows-1251

保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语

cp1252

Windows-1252

西欧

cp1253

windows-1253

希腊语

cp1254

windows-1254

土耳其

cp1255

windows-1255

希伯来语

cp1256

windows-1256

阿拉伯

cp1257

windows-1257

波罗的海语言

cp1258

windows-1258

越南语

cp65001

 

仅限Windows:Windows UTF-8(CP_UTF8

3.3 新版功能.

euc_jp

尤西峰

日本

euc_jis_2004

jisx0213,eucjis2004

日本

euc_jisx0213

eucjisx0213

日本

euc_kr

euckr,korean,ksc5601,ks_c-5601,ks_c-5601-1987,ksx1001,ks_x-1001

韩语

gb2312

中文,csiso58gb231280,euccn,euccn,eucgb2312-cn,gb2312-1980,gb2312-80,iso-

简体中文

gbk

936,cp936,ms936

统一中文

gb18030

gb18030-2000

统一中文

赫兹

hzgb,hz-gb,hz-gb-2312

简体中文

iso2022_jp

csiso2022jp,iso2022jp,iso-2022-jp

日本

iso2022_jp_1

iso2022jp-1,iso-2022-jp-1

日本

iso2022_jp_2

iso2022jp-2,iso-2022-jp-2

日语,韩语,简体中文,西欧,希腊语

iso2022_jp_2004

iso2022jp-2004,iso-2022-jp-2004

日本

iso2022_jp_3

iso2022jp-3,iso-2022-jp-3

日本

iso2022_jp_ext

iso2022jp-ext,iso-2022-jp-ext

日本

iso2022_kr

csiso2022kr,iso2022kr,iso-2022-kr

韩语

latin_1

iso-8859-1,iso8859-1,8859,cp819,latin,latin1,L1

西欧

iso8859_2

iso-8859-2,latin2,L2

中欧和东欧

iso8859_3

iso-8859-3,latin3,L3

世界语,马耳他语

iso8859_4

iso-8859-4,latin4,L4

波罗的海语言

iso8859_5

iso-8859-5,西里尔文

保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语

iso8859_6

iso-8859-6,arabic

阿拉伯

iso8859_7

iso-8859-7,greek,greek8

希腊语

iso8859_8

iso-8859-8,hebrew

希伯来语

iso8859_9

iso-8859-9,latin5,L5

土耳其

iso8859_10

iso-8859-10,latin6,L6

北欧语言

iso8859_11

iso-8859-11

泰语

iso8859_13

iso-8859-13,latin7,L7

波罗的海语言

iso8859_14

iso-8859-14,latin8,L8

凯尔特语

iso8859_15

iso-8859-15,latin9,L9

西欧

iso8859_16

iso-8859-16,latin10,L10

东南欧

johab

cp1361,ms1361

韩语

koi8_r

 

俄语

koi8_t

 

塔吉克

3.5 新版功能.

koi8_u

 

乌克兰

kz1048

kz_1048,strk1048_2002,rk1048

哈萨克

3.5 新版功能.

mac_cyrillic

maccyrillic

保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语

mac_greek

macgreek

希腊语

mac_iceland

maciceland

冰岛的

mac_latin2

maclatin2,maccentraleurope

中欧和东欧

mac_roman

macroman,macintosh

西欧

mac_turkish

macturkish

土耳其

ptcp154

csptcp154,pt154,cp154,西里尔文 - 亚洲

哈萨克

shift_jis

csshiftjis,shiftjis,sjis,s_jis

日本

shift_jis_2004

shiftjis2004,sjis_2004,sjis2004

日本

shift_jisx0213

shiftjisx0213,sjisx0213,s_jisx0213

日本

utf_32

U32,utf32

所有语言

utf_32_be

UTF-32BE

所有语言

utf_32_le

UTF-32LE

所有语言

utf_16

U16,utf16

所有语言

utf_16_be

UTF-16BE

所有语言

utf_16_le

UTF-16LE

所有语言

utf_7

U7,unicode-1-1-utf-7

所有语言

utf_8

U8,UTF,utf8

所有语言

utf_8_sig

 

所有语言

在 3.4 版更改: utf-16*和utf-32*编码器不再允许对代理代码点(U+D800U+DFFF)进行编码。 utf-32*解码器不再解码对应于代理码点的字节序列。

7.2.4. Python特定编码

许多预定义的编解码器是特定于Python的,所以它们的编解码器名称在Python之外没有意义。根据预期的输入和输出类型(请注意,虽然文本编码是编解码器最常见的用例,底层编解码器基础结构支持任意数据变换,而不仅仅是文本编码),下表中列出了这些。对于非对称编解码器,所述目的描述编码方向。

7.2.4.1. 文本编码

以下编解码器提供 strbytes 编码和 bytes-like objectstr 解码,类似于Unicode文本编码。

编解码器

别名

目的

idna

 

实施 RFC 3490,另见 encodings.idna。仅支持 errors='strict'

mbcs

ansi,dbcs

仅限Windows:根据ANSI代码页(CP_ACP)编码操作数

oem

 

仅限Windows:根据OEM代码页(CP_OEMCP)编码操作数

3.6 新版功能.

palmos

 

PalmOS 3.5的编码

punycode

 

实施 RFC 3492。不支持有状态的编解码器。

raw_unicode_escape

 

拉丁语-1编码与 \uXXXX\UXXXXXXXX 为其他代码点。现有反斜杠不以任何方式转义。它用于Python pickle协议。

未定义

 

针对所有转换(甚至是空字符串)提出异常。错误处理程序被忽略。

unicode_escape

 

编码适用于ASCII编码的Python源代码中的Unicode字面量,除了引号不转义。从Latin-1源代码解码。注意,Python源代码实际上默认使用UTF-8。

unicode_internal

 

返回操作数的内部表示。不支持有状态的编解码器。

3.3 版后已移除: 这个表示被 PEP 393 废弃。

7.2.4.2. 二进制变换

以下编解码器提供二进制转换:bytes-like objectbytes 映射。它们不受 bytes.decode() (仅生成 str 输出)支持。

编解码器

别名

目的

编码器/解码器

base64_codec [1]

base64,base_64

将操作数转换为多行MIME base64(结果始终包括尾随 '\n'

在 3.4 版更改: 接受任何 bytes-like object 作为编码和解码的输入

base64.encodebytes() / base64.decodebytes()

bz2_codec

bz2

使用bz2压缩操作数

bz2.compress() / bz2.decompress()

hex_codec

十六进制

将操作数转换为十六进制表示,每字节两个数字

binascii.b2a_hex() / binascii.a2b_hex()

quopri_codec

quopri,quotedprintable,quoted_printable

将操作数转换为MIME引用的可打印

quopri.encode()quotetabs=True / quopri.decode()

uu_codec

u

使用uuencode转换操作数

uu.encode() / uu.decode()

zlib_codec

zip,zlib

使用gzip压缩操作数

zlib.compress() / zlib.decompress()

[1]

除了 字节状对象'base64_codec' 还接受 str 的仅ASCII实例用于解码

3.2 新版功能: 恢复二进制变换。

在 3.4 版更改: 恢复二进制变换的别名。

7.2.4.3. 文本转换

以下编解码器提供文本转换:strstr 映射。 str.encode() 不支持它(仅生成 bytes 输出)。

编解码器

别名

目的

rot_13

rot13

返回操作数的Caesar-cipher加密

3.2 新版功能: 恢复 rot_13 文本转换。

在 3.4 版更改: 恢复 rot13 别名。

7.2.5. encodings.idna —应用程序中的国际化域名

此模块实现 RFC 3490 (应用程序中的国际化域名)和 RFC 3492 (国际化域名(IDN)的Nameprep:A Stringprep配置文件)。它基于 punycode 编码和 stringprep

这些RFC一起定义了一种协议,以支持域名中的非ASCII字符。包含非ASCII字符(如 www.Alliancefrançaise.nu)的域名将转换为ASCII兼容编码(ACE,例如 www.xn--alliancefranaise-npb.nu)。域名的ACE形式随后用于协议不允许任意字符的所有位置,例如DNS查询,HTTP Host 字段等。这种转换在应用程序中执行;如果可能对用户不可见:应用程序应将Unicode域标签透明地转换为IDNA,并将ACE标签转换回Unicode,然后再将其显示给用户。

Python支持以下几种方式的转换:idna 编解码器在Unicode和ACE之间执行转换,基于 RFC 3490section 3.1 (1)中定义的分隔符字符将输入字符串分为标签,并根据需要将每个标签转换为ACE,输入字节字符串到基于 . 分隔符的标签,并将任何ACE标签转换为unicode。此外,socket 模块将Unicode主机名透明地转换为ACE,以便应用程序在将主机名传递给套接字模块时不必关心主机名本身的转换。此外,具有主机名作为功能参数的模块(例如 http.clientftplib)接受Unicode主机名(则 http.client 还在 Host 字段透明地发送IDNA主机名,如果发送该字段)。

当从线路接收主机名时(例如在反向名称查找中),不执行自动转换为Unicode:应用程序希望向用户提供这样的主机名时,应将其解码为Unicode。

模块 encodings.idna 还实现nameprep过程,其对主机名执行某些规范化,以实现国际域名的不区分大小写,并且统一类似的字符。如果需要,可以直接使用nameprep功能。

encodings.idna.nameprep(label)

返回 label 的修订版本。实现当前假设查询字符串,因此 AllowUnassigned 为true。

encodings.idna.ToASCII(label)

将标签转换为ASCII,如 RFC 3490 中指定。 UseSTD3ASCIIRules 假定为假。

encodings.idna.ToUnicode(label)

将标签转换为Unicode,如 RFC 3490 中指定。

7.2.6. encodings.mbcs — Windows ANSI代码页

根据ANSI代码页(CP_ACP)编码操作数。

可用性:仅限Windows。

在 3.3 版更改: 支持任何错误处理程序。

在 3.2 版更改: 在3.2之前,errors 参数被忽略; 'replace' 总是用于编码,并且 'ignore' 解码。

7.2.7. encodings.utf_8_sig —具有BOM签名的UTF-8编解码器

此模块实现UTF-8编解码器的一个变体:在编码时,UTF-8编码的BOM将添加到UTF-8编码的字节前。对于有状态编码器,这只做一次(在第一次写入字节流时)。对于解码,在数据开始处的可选的UTF-8编码的BOM将被跳过。