python / 3.7.2rc1 / all / library-codecs.html

编解码器—编解码器注册表和 Base Class

源代码: Lib/codecs.py


此模块为标准 Python 编解码器(编码器和解码器)定义 Base Class,并提供对内部 Python 编解码器注册表的访问,该注册表 Management 编解码器和错误处理查找过程。大多数标准编解码器是text encodings,它们将文本编码为字节,但也提供了将文本编码为文本,字节编码为字节的编解码器。定制编解码器可以在任意类型之间进行编码和解码,但是某些模块Function仅限于text encodings或编码为bytes的编解码器使用。

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

  • codecs. encode(* obj encoding ='utf-8' errors ='strict'*)
    • 使用为* encoding 注册的编解码器对 obj *进行编码。

错误可能会给您设置所需的错误处理方案。默认错误处理程序为'strict',这意味着编码错误会引发ValueError(或更特定于编解码器的子类,例如UnicodeEncodeError)。有关编解码器错误处理的更多信息,请参考编解码器 Base Class

  • codecs. decode(* obj encoding ='utf-8' errors ='strict'*)
    • 使用为* encoding 注册的编解码器对 obj *进行解码。

错误可能会给您设置所需的错误处理方案。默认错误处理程序为'strict',这意味着解码错误会引发ValueError(或更多特定于编解码器的子类,例如UnicodeDecodeError)。有关编解码器错误处理的更多信息,请参考编解码器 Base Class

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

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

首先在注册表的缓存中查找编码。如果找不到,将扫描已注册的搜索Function列表。如果未找到CodecInfo对象,则引发LookupError。否则,CodecInfo对象将存储在缓存中并返回给调用方。

    • class * codecs. CodecInfo(* encode decode streamreader = None streamwriter = None incrementalencoder = None incrementaldecoder = None name = None *)
    • 查找编解码器注册表时的编解码器详细信息。构造函数参数存储在相同名称的属性中:
  • name

    • 编码的名称。
  • encode

    • decode
      • Stateless 编码和解码Function。这些必须是与编解码器实例的encode()decode()方法具有相同接口的函数或方法(请参见Codec Interface)。这些Function或方法应在 Stateless 模式下工作。
  • incrementalencoder

    • incrementaldecoder
      • 增量编码器和解码器类或工厂Function。它们必须提供分别由 Base ClassIncrementalEncoderIncrementalDecoder定义的接口。增量编解码器可以维持状态。
  • streamwriter

    • streamreader
      • 流 Writer 和 Reader 类或工厂Function。它们必须提供分别由 Base ClassStreamWriterStreamReader定义的接口。流编解码器可以维护状态。

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

  • codecs. getencoder(编码)
    • 查找给定编码的编解码器,并返回其编码器Function。

如果找不到编码,则引发LookupError

  • codecs. getdecoder(编码)
    • 查找编解码器以获取给定的编码,然后返回其解码器Function。

如果找不到编码,则引发LookupError

  • codecs. getincrementalencoder(编码)
    • 查找给定编码的编解码器,并返回其增量编码器类或工厂Function。

如果找不到编码或编解码器不支持增量编码器,则引发LookupError

  • codecs. getincrementaldecoder(编码)
    • 查找给定编码的编解码器,并返回其增量解码器类或工厂函数。

在找不到编码或编解码器不支持增量解码器的情况下引发LookupError

  • codecs. getreader(编码)
    • 查找给定编码的编解码器,并返回其StreamReader类或工厂函数。

如果找不到编码,则引发LookupError

  • codecs. getwriter(编码)
    • 查找给定编码的编解码器,并返回其StreamWriter类或工厂函数。

如果找不到编码,则引发LookupError

pass注册合适的编解码器搜索Function,可以使用自定义编解码器:

  • codecs. register(* search_function *)
    • 注册编解码器搜索Function。搜索函数应采用一个参数,即所有小写字母的编码名称,并返回CodecInfo对象。如果搜索Function找不到给定的编码,则应返回None

Note

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

虽然推荐使用内置的open()和关联的io模块来处理编码的文本文件,但是此模块提供了附加的 Util Function和类,这些Function和类在处理二进制文件时允许使用范围更广的编解码器:

  • codecs. open(* filename mode ='r' encoding = None errors ='strict' buffering = -1 *)
    • 使用给定的* mode *打开编码的文件,并返回StreamReaderWriter的实例,以提供透明的编码/解码。默认文件模式为'r',这意味着以读取模式打开文件。

Note

底层编码文件始终以二进制模式打开。读写时不会自动完成'\n'的转换。 * mode *参数可以是内置open()函数可接受的任何二进制模式。 'b'自动添加。

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

可以给出* errors *来定义错误处理。默认为'strict',如果发生编码错误,则会引发ValueError

  • buffering *具有与内置open()函数相同的含义。默认值为-1,这意味着将使用默认缓冲区大小。
  • 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(迭代器编码,* errors ='strict'** kwargs *)
    • 使用增量编码器对* iterator *提供的 Importing 进行迭代编码。此函数是generator。 * errors *参数(以及任何其他关键字参数)将传递到增量编码器。

此Function要求编解码器接受文本str对象进行编码。因此,它不支持字节对字节编码器,例如base64_codec

  • codecs. iterdecode(迭代器编码,* errors ='strict'** kwargs *)
    • 使用增量解码器对* iterator *提供的 Importing 进行迭代解码。此函数是generator。 * errors *参数(以及任何其他关键字参数)将传递到增量解码器。

此Function要求编解码器接受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 字节 Sequences 标记(BOM)。在 UTF-16 和 UTF-32 数据流中使用它们来指示使用的字节 Sequences,在 UTF-8 中将它们用作 Unicode 签名。 BOM_UTF16BOM_UTF16_BEBOM_UTF16_LE,具体取决于平台的本机字节 Sequences,BOMBOM_UTF16的别名,BOM_LEBOM_UTF16_LE的别名,而BOM_BEBOM_UTF16_BE的别名。其他代表 UTF-8 和 UTF-32 编码的 BOM。

编解码器 Base Class

codecs模块定义了一组 Base Class,这些 Base Class 定义了用于使用编解码器对象的接口,也可以用作自定义编解码器实现的基础。

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

Error Handlers

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

Value Meaning
'strict' 提高UnicodeError(或子类);这是默认值。在strict_errors()中实现。
'ignore' 忽略格式错误的数据,continue 进行操作,恕不另行通知。已在ignore_errors()中实现。

以下错误处理程序仅适用于text encodings

Value Meaning
'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。)

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

Value Codecs Meaning
'surrogatepass' utf-8,utf-16,utf-32,utf-16-be,utf-16-le,utf-32-be,utf-32-le 允许对代理代码进行编码和解码。这些编解码器通常将代理的出现视为错误。

版本 3.1 中的新Function:'surrogateescape''surrogatepass'错误处理程序。

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

版本 3.5 中的新Function:'namereplace'错误处理程序。

在版本 3.5 中进行了更改:'backslashreplace'错误处理程序现在可用于解码和翻译。

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

  • codecs. register_error(* name error_handler *)
    • 在名称* name 下注册错误处理函数 error_handler 。如果将 name 指定为 errors 参数,则在编码和解码过程中如果发生错误,将调用 error_handler *参数。

对于编码,将使用UnicodeEncodeError实例调用* error_handler *,该实例包含有关错误位置的信息。错误处理程序必须引发此异常或不同的异常,或者返回一个 Tuples,并替换 Importing 的不可编码部分以及应 continue 编码的位置。替换可以是strbytes。如果替换为字节,则编码器将简单地将其复制到输出缓冲区中。如果替换是字符串,编码器将对替换进行编码。在原始 Importing 的指定位置 continue 编码。负位置值将被视为相对于 Importing 字符串的末尾。如果结果位置超出范围,则将引发IndexError

解码和翻译的工作方式相似,只是将UnicodeDecodeErrorUnicodeTranslateError传递给处理程序,并且将错误处理程序中的替换内容直接放入输出中。

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

  • codecs. lookup_error(* name *)
    • 返回先前以名称* name *注册的错误处理程序。

引发LookupError以防找不到处理程序。

以下标准错误处理程序也可作为模块级Function使用:

  • codecs. strict_errors(* exception *)

    • 实现'strict'错误处理:每个编码或解码错误都会引发UnicodeError
  • codecs. replace_errors(* exception *)

    • 实现'replace'错误处理(仅适用于text encodings):用'?'代替编码错误(由编解码器编码),用'\ufffd'(Unicode 替换字符)替代解码错误。
  • codecs. ignore_errors(* exception *)

    • 实现'ignore'错误处理:格式错误的数据将被忽略,并且 continue 进行编码或解码,恕不另行通知。
  • codecs. xmlcharrefreplace_errors(* exception *)

    • 实现'xmlcharrefreplace'错误处理(仅适用于text encodings编码):无法编码的字符将替换为适当的 XML 字符引用。
  • codecs. backslashreplace_errors(* exception *)

    • 实现'backslashreplace'错误处理(仅适用于text encodings):格式错误的数据由反斜杠转义序列代替。
  • codecs. namereplace_errors(* exception *)

    • 实现'namereplace'错误处理(仅适用于text encodings编码):无法编码的字符由\N{...}转义序列代替。

3.5 版中的新Function。

Stateless 编码和解码

基本的Codec类定义了这些方法,这些方法还定义了 Stateless 编码器和解码器的Function接口:

  • Codec. encode(* input * [,* errors *])
    • 对对象* input *进行编码,并返回一个 Tuples(输出对象,使用的长度)。例如,text encoding使用特定的字符集编码(例如cp1252iso-8859-1)将字符串对象转换为字节对象。
  • errors *参数定义要应用的错误处理。默认为'strict'处理。

该方法可能不将状态存储在Codec实例中。 StreamWriter用于必须保持状态以提高编码效率的编解码器。

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

  • Codec. decode(* input * [,* errors *])
    • 解码对象* input *并返回一个 Tuples(输出对象,消耗的长度)。例如,对于text encoding,解码将使用特定字符集编码编码的字节对象转换为字符串对象。

对于文本编码和逐字节编解码器,* input *必须是一个字节对象或提供只读缓冲区接口的对象(例如,缓冲区对象和内存 Map 文件)。

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

该方法可能不将状态存储在Codec实例中。对于必须保持状态以提高解码效率的编解码器,请使用StreamReader

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

增量编码和解码

IncrementalEncoderIncrementalDecoder类提供用于增量编码和解码的基本接口。Importing 的编码/解码不是pass一次调用 Stateless 编码器/解码器函数来完成的,而是pass多次调用增量式编码器/解码器的encode()/decode()方法来完成的。增量编码器/解码器在方法调用期间跟踪编码/解码过程。

encode()/decode()方法的调用的合并输出与将所有单个 Importing 合并为一个相同,并且使用 Stateless 编码器/解码器对该 Importing 进行编码/解码。

IncrementalEncoder Objects

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

    • class * codecs. IncrementalEncoder(* errors ='strict'*)

所有增量编码器都必须提供此构造函数接口。它们可以自由添加其他关键字参数,但是 Python 编解码器注册表仅使用此处定义的参数。

IncrementalEncoder可以pass提供* errors *关键字参数来实现不同的错误处理方案。有关可能的值,请参见Error Handlers

  • errors *参数将分配给相同名称的属性。分配给该属性可以在IncrementalEncoder对象的生存期内在不同的错误处理策略之间进行切换。
  • encode(* object * [,* final *])

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

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

    • 返回编码器的当前状态,该状态必须为整数。实现应确保0是最常见的状态。 (比整型状态复杂的状态可以pass封送/分接状态并将结果字符串的字节编码为整数来转换为整数.)
  • setstate(* state *)

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

IncrementalDecoder Objects

IncrementalDecoder类用于多步解码 Importing。它定义了每个增量解码器都必须定义的以下方法,以便与 Python 编解码器注册表兼容。

    • class * codecs. IncrementalDecoder(* errors ='strict'*)

所有增量解码器都必须提供此构造函数接口。它们可以自由添加其他关键字参数,但是 Python 编解码器注册表仅使用此处定义的参数。

IncrementalDecoder可以pass提供* errors *关键字参数来实现不同的错误处理方案。有关可能的值,请参见Error Handlers

  • errors *参数将分配给相同名称的属性。分配给该属性可以在IncrementalDecoder对象的生存期内在不同的错误处理策略之间进行切换。
  • decode(* object * [,* final *])

    • 解码* object *(考虑解码器的当前状态)并返回生成的解码对象。如果这是对decode() * final 的最后一次调用,则必须为 true(默认值为 false)。如果 final *为 true,则解码器必须完全解码 Importing,并且必须刷新所有缓冲区。如果这是不可能的(例如由于 Importing 末尾的字节序列不完整),则它必须像在 Stateless 情况下(可能会引发异常)一样启动错误处理。
  • reset ( )

    • 将解码器重置为初始状态。
  • getstate ( )

    • 返回解码器的当前状态。这必须是包含两个项的 Tuples,第一个必须是包含仍未解码的 Importing 的缓冲区。第二个必须是整数,并且可以是其他状态信息。 (实现应确保0是最常见的附加状态信息.)如果此附加状态信息是0,则必须可以将解码器设置为没有 Importing 缓冲的状态,并将0设置为附加状态信息,以便将先前缓冲的 Importing 馈送到解码器会使它返回先前的状态,而不会产生任何输出。 (可以pass封送/整理信息并将结果字符串的字节编码为整数来将比整数更复杂的其他状态信息转换为整数.)
  • setstate(* state *)

    • 将解码器的状态设置为* state *。 * state *必须是getstate()返回的解码器状态。

流编码和解码

StreamWriterStreamReader类提供了通用的工作接口,可用于非常轻松地实现新的编码子模块。有关执行此操作的示例,请参见encodings.utf_8

StreamWriter Objects

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

    • class * codecs. StreamWriter(* stream errors ='strict'*)

所有流编写器都必须提供此构造函数接口。它们可以自由添加其他关键字参数,但是 Python 编解码器注册表仅使用此处定义的参数。

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

StreamWriter可以pass提供* errors *关键字参数来实现不同的错误处理方案。有关底层流编解码器可能支持的标准错误处理程序,请参见Error Handlers

  • errors *参数将分配给相同名称的属性。分配给该属性可以在StreamWriter对象的生存期内在不同的错误处理策略之间进行切换。
  • write(* object *)

    • 将编码后的对象的内容写入流中。
  • writelines(列表)

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

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

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

除上述方法外,StreamWriter还必须从基础流继承所有其他方法和属性。

StreamReader Objects

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

    • class * codecs. StreamReader(* stream errors ='strict'*)

所有流阅读器都必须提供此构造函数接口。它们可以自由添加其他关键字参数,但是 Python 编解码器注册表仅使用此处定义的参数。

  • stream *参数必须是类似文件的对象,可以打开以读取文本或二进制数据(适用于特定编解码器)。

StreamReader可以pass提供* errors *关键字参数来实现不同的错误处理方案。有关底层流编解码器可能支持的标准错误处理程序,请参见Error Handlers

  • errors *参数将分配给相同名称的属性。分配给该属性可以在StreamReader对象的生存期内在不同的错误处理策略之间进行切换。

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

  • read([[* size * [,* chars * [,* firstline *]]])
    • 从流中解码数据并返回结果对象。
  • chars *参数指示要返回的已解码代码点或字节数。 read()方法绝不会返回比请求更多的数据,但是如果没有足够的可用空间,则返回的数据可能更少。

  • size *参数指示要读取以进行解码的已编码字节或代码点的大约最大数量。解码器可以适当修改此设置。默认值-1 表示要尽可能多地读取和解码。此参数旨在避免必须一步解码大型文件。

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

该方法应使用贪婪读取策略,这意味着它应读取编码定义和给定大小(例如,如果流上有可选的编码结尾或状态标记,则也应读取它们。

  • readline([[* size * [,* keepends *]])
    • 从 Importing 流中读取一行并返回解码后的数据。
  • size *(如果给定的话)作为 size 参数传递给流的read()方法。

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

  • readlines([* sizehint * [,* keepends *]])
    • 读取 Importing 流上所有可用的行,并将它们作为行列表返回。

行尾使用编解码器的decode()方法实现,并且如果* keepends *为 true,则将其包括在列表条目中。

如果给出* sizehint ,则作为 size *参数传递给流的read()方法。

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

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

除上述方法外,StreamReader还必须从基础流继承所有其他方法和属性。

StreamReaderWriter Objects

StreamReaderWriter是一个便利类,它允许包装可在读取和写入模式下工作的流。

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

    • class * codecs. StreamReaderWriter(* stream Reader Writer errors ='strict'*)
    • 创建一个StreamReaderWriter实例。 * stream *必须是类似文件的对象。 * Reader Writer *必须是工厂函数或提供StreamReaderStreamWriter接口的类。错误处理的方式与为流读取器和写入器定义的方式相同。

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

StreamRecoder Objects

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

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

    • class * codecs. StreamRecoder(* stream encode decode Reader Writer errors ='strict'*)
    • 创建一个StreamRecoder实例,该实例实现双向转换:* encode decode 在前端工作—调用read()write()的代码可见的数据,而 Reader Writer 在后端工作–数据在流*。

您可以使用这些对象进行透明的转码,例如,从 Latin-1 到 UTF-8 并返回。

  • stream *参数必须是类似文件的对象。

  • encode decode *参数必须遵守Codec接口。 * Reader Writer *必须是工厂函数或类,分别提供StreamReaderStreamWriter接口的对象。

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

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

编码和 Unicode

字符串在内部存储为0x00x10FFFF范围内的代码点序列。 (有关实现的更多详细信息,请参见 PEP 393。)一旦在 CPU 和内存之外使用了字符串对象,字节序以及如何将这些数组作为字节存储就成为问题。与其他编解码器一样,将字符串序列化为字节序列称为* encoding ,从字节序列重新创建字符串称为 decoding *。有多种不同的文本序列化编解码器,它们统称为text encodings

最简单的文本编码(称为'latin-1''iso-8859-1')将代码点 0–255Map 到字节0x00xff,这意味着包含高于U+00FF的代码点的字符串对象无法使用此编解码器进行编码。这样做将引发一个类似于以下内容的UnicodeEncodeError(尽管错误消息的详细信息可能有所不同):UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256)

还有另一组编码(所谓的 charmap 编码),它们选择所有 Unicode 代码点的不同子集,以及如何将这些代码点 Map 到字节0x00xff。要查看如何完成此操作,只需打开例如encodings/cp1252.py(这是主要在 Windows 上使用的编码)。有一个包含 256 个字符的字符串常量,向您显示哪个字符 Map 到哪个字节值。

所有这些编码只能编码 Unicode 中定义的 1114112 个代码点中的 256 个。可以存储每个 Unicode 代码点的一种简单明了的方法是将每个代码点存储为四个连续的字节。有两种可能性:以大字节序或小字节序存储字节。这两种编码分别称为UTF-32-BEUTF-32-LE。它们的缺点是例如您在小型字节序计算机上使用UTF-32-BE,则始终必须在编码和解码时交换字节。 UTF-32避免了此问题:字节将始终保持自然字节序。当这些字节由具有不同字节序的 CPU 读取时,则必须交换字节。为了能够检测到UTF-16UTF-32字节序列的字节序,有所谓的 BOM(“字节 Sequences 标记”)。这是 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+2060(WORD JOINER)担任此角色)。尽管如此,Unicode 软件仍然必须能够同时扮演U+FEFF的角色:作为 BOM,它是一种确定编码字节存储布局的设备,一旦字节序列被解码为字符串,它就会消失;作为ZERO WIDTH NO-BREAK SPACE,它是正常字符,将像其他字符一样被解码。

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

Range Encoding
U-00000000U-0000007F 0xxxxxxx
U-00000080U-000007FF 110xxxxx 10xxxxxx
U-00000800U-0000FFFF 1110 xxxx 10xxxxxx 10xxxxxx
U-00010000U-0010FFFF 11110 xxx 10xxxxxx 10xxxxxx 10xxxxxx

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

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

没有外部信息,就不可能可靠地确定使用哪种编码对字符串进行编码。每种 charmap 编码都可以解码任何随机字节序列。但是,对于 UTF-8,这是不可能的,因为 UTF-8 字节序列的结构不允许任意字节序列。为了提高检测 UTF-8 编码的可靠性,Microsoft 为其 Notepad 程序发明了 UTF-8 变体(Python 2.5 调用"utf-8-sig"):在将任何 Unicode 字符写入文件之前,UTF-将写入 8 个编码的 BOM(看起来像一个字节序列:0xef0xbb0xbf)。因为任何用 charmap 编码的文件都以这些字节值开头(例如,Map 到

Note

带有拉丁文的拉丁文小写字母 I

正确的双角引号

反问号

在 iso-8859-1 中),这增加了从字节序列中正确猜出utf-8-sig编码的可能性。因此,这里的 BOM 不是用来确定用于生成字节序列的字节 Sequences,而是作为有助于猜测编码的签名。在对 utf-8-sig 编解码器进行编码时,会将0xef0xbb0xbf作为前三个字节写入文件。在解码utf-8-sig时,如果这三个字节显示为文件中的前三个字节,则会跳过这三个字节。在 UTF-8 中,不建议使用 BOM,通常应避免使用 BOM。

Standard Encodings

Python 带有许多内置的编解码器,这些编解码器既可以实现为 C 函数,也可以带有字典作为 Map 表。下表按名称列出了编解码器,以及一些常用别名,以及可能使用编码的语言。别名列表或语言列表都不是详尽无遗的。请注意,仅大小写不同或使用连字符而不是下划线的拼写替代也是有效的别名;因此,例如'utf-8''utf_8'编解码器的有效别名。

CPython 实现细节: 一些常见的编码可以绕过编解码器查找机制以提高性能。这些优化机会只有 CPython 才能识别出一组有限的(不区分大小写)别名:utf-8,utf8,latin-1,latin1,iso-8859-1,iso8859-1,mbcs(仅 Windows),ascii,us -ascii,utf-16,utf16,utf-32,utf32,并使用下划线代替破折号。对这些编码使用替代别名可能会导致执行速度变慢。

在版本 3.6 中进行了更改:us-ascii 意识到了优化机会。

许多字符集支持相同的语言。它们在各个字符(例如是否支持 EURO SIGN)以及将字符分配给代码位置方面有所不同。特别是对于欧洲语言,通常存在以下变体:

  • ISO 8859 代码集

  • Microsoft Windows 代码页,通常从 8859 代码集派生,但是将控制字符替换为其他图形字符

  • IBM EBCDIC 代码页

  • IBM PC 代码页,它与 ASCII 兼容

Codec Aliases Languages
ascii 646, us-ascii English
big5 big5-tw, csbig5 Traditional Chinese
big5hkscs big5-hkscs, hkscs Traditional Chinese
cp037 IBM037, IBM039 English
cp273 273,IBM273,csIBM273 German


3.4 版中的新Function。
|cp424|EBCDIC-CP-HE, IBM424|Hebrew|
|cp437|437, IBM437|English|
| cp500 | EBCDIC-CP-BE,EBCDIC-CP-CH,IBM500 |西欧|
|cp720||Arabic|
|cp737||Greek|
|cp775|IBM775|Baltic languages|
| cp850 | 850,IBM850 |西欧|
| cp852 | 852,IBM852 |中欧和东欧|
| cp855 | 855,IBM855 |保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语|
|cp856||Hebrew|
|cp857|857, IBM857|Turkish|
| cp858 | 858,IBM858 |西欧|
|cp860|860, IBM860|Portuguese|
| cp861 | 861,CP-IS,IBM861 |冰岛|
|cp862|862, IBM862|Hebrew|
|cp863|863, IBM863|Canadian|
|cp864|IBM864|Arabic|
| cp865 | 865,IBM865 |丹麦语,挪威|
|cp866|866, IBM866|Russian|
| cp869 | 869,CP-GR,IBM869 |希腊|
|cp874||Thai|
|cp875||Greek|
| cp932 | 932,ms932,mskanji,ms-kanji |日语|
| cp949 | 949,ms949,uhc |韩国|
| cp950 | 950,ms950 |繁体中文|
|cp1006||Urdu|
|cp1026|ibm1026|Turkish|
| cp1125 | 1125,ibm1125,cp866u,ruscii |乌克兰语
3.4 版中的新Function。
|cp1140|ibm1140|Western Europe|
| cp1250 | windows-1250 |中欧和东欧|
| cp1251 | windows-1251 |保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语|
|cp1252|windows-1252|Western Europe|
|cp1253|windows-1253|Greek|
|cp1254|windows-1254|Turkish|
|cp1255|windows-1255|Hebrew|
|cp1256|windows-1256|Arabic|
|cp1257|windows-1257|Baltic languages|
|cp1258|windows-1258|Vietnamese|
| euc_jp | eucjp,ujis,u-jis |日语|
|euc_jis_2004|jisx0213, eucjis2004|Japanese|
|euc_jisx0213|eucjisx0213|Japanese|
| euc_kr | euckr,韩国语,ksc5601,ks_c-5601,ks_c-5601-1987,ksx1001,ks_x-1001 |韩国|
| gb2312 |中文,csiso58gb231280,euc-cn,euccn,eucgb2312-cn,gb2312-1980,gb2312-80,iso-ir-58 |简体中文|
| gbk | 936,cp936,ms936 |统一中文|
|gb18030|gb18030-2000|Unified Chinese|
| hz | hzgb,hz-gb,hz-gb-2312 |简体中文|
| iso2022_jp | csiso2022jp,iso2022jp,iso-2022-jp |日语|
|iso2022_jp_1|iso2022jp-1, iso-2022-jp-1|Japanese|
|| iso2022_jp_2 | iso2022jp-2,iso-2022-jp-2 |日语,韩语,简体中文,西欧,希腊语|
|iso2022_jp_2004|iso2022jp-2004, iso-2022-jp-2004|Japanese|
|iso2022_jp_3|iso2022jp-3, iso-2022-jp-3|Japanese|
|iso2022_jp_ext|iso2022jp-ext, iso-2022-jp-ext|Japanese|
| iso2022_kr | csiso2022kr,iso2022kr,iso-2022-kr |韩国|
| latin_1 | iso-8859-1,iso8859-1、8859,cp819,拉丁语,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|Arabic|
|| iso8859_7 | iso-8859-7,希腊语,希腊 8 |希腊语|
|iso8859_8|iso-8859-8, hebrew|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|Korean|
|koi8_r||Russian|
|koi8_t||Tajik
版本 3.5 中的新Function。
|koi8_u||Ukrainian|
| kz1048 | kz_1048,strk1048_2002,rk1048 |哈萨克
版本 3.5 中的新Function。
| mac_cyrillic | maccyrillic |保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语|
|mac_greek|macgreek|Greek|
|mac_iceland|maciceland|Icelandic|
| mac_latin2 | maclatin2,maccentraleurope |中欧和东欧|
| mac_roman | macintosh 的宏指令|西欧|
|mac_turkish|macturkish|Turkish|
| 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|all languages|
|utf_32_le|UTF-32LE|all languages|
| utf_16 | U16,utf16 |所有语言|
|utf_16_be|UTF-16BE|all languages|
|utf_16_le|UTF-16LE|all languages|
| utf_7 | U7,unicode-1-1-utf-7 |所有语言|
| utf_8 | U8,UTF,utf8,cp65001 |所有语言|
|utf_8_sig||all languages|

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

在 3.8 版中进行了更改:cp65001现在是utf_8的别名。

Python 特定的编码

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

Text Encodings

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

Codec Aliases Meaning
idna 实施 RFC 3490,另请参见encodings.idna。仅支持errors='strict'
mbcs ansi, dbcs 仅限 Windows:根据 ANSI 代码页(CP_ACP)对操作数进行编码。
oem 仅限 Windows:根据 OEM 代码页(CP_OEMCP)对操作数进行编码。


3.6 版中的新Function。
| palmos || PalmOS 3.5 的编码。
| punycode ||实施
RFC 3492。不支持有状态编解码器。
| raw_unicode_escape ||其他代码点使用\uXXXX\UXXXXXXXX进行拉丁 1 编码。现有的反斜杠不会以任何方式转义。在 Python pickle 协议中使用。
| undefined ||引发所有转换的异常,即使是空字符串也是如此。错误处理程序将被忽略。
| unicode_escape ||适合作为 ASCII 编码的 Python 源代码中的 UnicodeLiterals 的内容的编码,除了不对引号进行转义。从 Latin-1 源代码解码。注意,Python 源代码实际上默认情况下使用 UTF-8.

在版本 3.8 中进行了更改:删除了“ unicode_internal”编解码器。

Binary Transforms

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

Codec Aliases Meaning 编码器/解码器
base64_codec [1] base64, base_64 将操作数转换为多行 MIME base64(结果始终包含尾随'\n')。

在版本 3.4 中进行了更改:接受任何bytes-like object作为编码和解码的 Importing
base64.encodebytes()/base64.decodebytes()
bz2_codec bz2 使用 bz2 压缩操作数。 bz2.compress()/bz2.decompress()
hex_codec hex 将操作数转换为十六进制表示,每字节两位。 binascii.b2a_hex()/binascii.a2b_hex()
quopri_codec quopri,quotedprintable,quoted_printable 将操作数转换为 MIME quoted printable。 quopri.encode()quotetabs=True/quopri.decode()
uu_codec uu 使用 uuencode 转换操作数。 uu.encode()/uu.decode()
zlib_codec zip,zlib 使用 gzip 压缩操作数。 zlib.compress()/zlib.decompress()

版本 3.2 中的新Function:恢复二进制转换。

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

Text Transforms

以下编解码器提供了文本转换:strstr的 Map。 str.encode()不支持(仅产生bytes输出)。

Codec Aliases Meaning
rot_13 rot13 返回操作数的 Caesar 密码加密。

版本 3.2 中的新Function:恢复rot_13文本转换。

在版本 3.4 中进行了更改:恢复rot13别名。

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

此模块实现 RFC 3490(应用程序中的国际化域名)和 RFC 3492(Nameprep:国际化域名(IDN)的 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 3490 的 3.1 节中定义的分隔符将 Importing 字符串分隔为标签,然后根据需要将每个标签转换为 ACE,然后将 Importing 字节字符串分隔为基于.分隔符的标签,并将找到的所有 ACE 标签转换为 unicode。此外,socket模块将 Unicode 主机名透明地转换为 ACE,因此在将主机名传递给套接字模块时,应用程序不必担心转换主机名本身。最重要的是,以主机名作为函数参数的模块(例如http.clientftplib)接受 Unicode 主机名(http.client然后也将在* Host *字段中透明地发送 IDNA 主机名(如果它完全发送该字段)。

从网络接收主机名时(例如,反向查找),不会自动转换为 Unicode:希望向用户提供此类主机名的应用程序应将其解码为 Unicode。

模块encodings.idna还实现了名称准备过程,该过程对主机名执行某些规范化操作,以实现国际域名的区分大小写并统一相似的字符。如果需要,可以直接使用 nameprep 函数。

  • encodings.idna. nameprep(* label *)

    • 返回* label *的名称准备版本。该实现当前采用查询字符串,因此AllowUnassigned为 true。
  • encodings.idna. ToASCII(* label *)

    • 按照 RFC 3490的指定将标签转换为 ASCII。 UseSTD3ASCIIRules假定为假。
  • encodings.idna. ToUnicode(* label *)

    • 按照 RFC 3490中的指定将标签转换为 Unicode。

encodings.mbcs-Windows ANSI 代码页

此模块实现 ANSI 代码页(CP_ACP)。

Availability:仅 Windows。

在版本 3.3 中更改:支持所有错误处理程序。

在 3.2 版中进行了更改:在 3.2 版之前,* errors *参数被忽略; 'replace'始终用于编码,而'ignore'始终用于解码。

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

该模块实现了 UTF-8 编解码器的变体。在编码时,UTF-8 编码的 BOM 将位于 UTF-8 编码的字节之前。对于有状态编码器,此操作仅执行一次(第一次写入字节流时)。解码时,将跳过数据开头的可选 UTF-8 编码 BOM。