所有这些编码格式只能对 Unicode 所定义的 1114112 个码位中的 256 个进行编码。 一种能够存储每个 Unicode 码位的简单而直接的办法就是将每个友们存储为四个连续的字节。 存在两种不同的可能性:以大端序存储或以小端序存储。 这两种编码格式分别被称为 UTF-32-BE
和 UTF-32-LE
。 他们共有的缺点可以举例说明:如果你在一台小端序的机器上使用 UTF-32-BE
则你必须在编码和解码时翻转字节。 UTF-32
避免了这个问题:字节的排列将总是使用自然端序。 当这些字节被具有不同端序的 CPU 读取时,则必须进行字节翻转。 为了能够检测 UTF-16
或 UTF-32
字节序列的大小端序,可以使用所谓的 BOM ("字节顺序标记")。 这对应于 Unicode 字符 U+FEFF
。 此字符可被添加到每个 UTF-16
或 UTF-32
字节序列的开头。 此字符的字节翻转版本 (0xFFFE
) 是一个不可出现于 Unicode 文本中的非法字符。 因此当发现一个 UTF-16
或 UTF-32
字节序列的首个字符是 U+FFFE
时,就必须在解码时进行字节翻转。 不幸的是字符 U+FEFF
还有第二个含义 ZERO WIDTH NO-BREAK SPACE
: 即宽度为零并且不允许用来拆分单词的字符。 它可以被用来为语言分析算法提供提示。 在 Unicode 4.0 中使用 U+FEFF
表示 ZERO WIDTH NO-BREAK SPACE
已被弃用 (改用 U+2060
(WORD 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 字符):
在没有外部信息的情况下将不可能毫无疑义地确定一个字符串使用了何种编码格式。 每种字符映射编码格式都可以解码任意的随机字节序列。 然而对 UTF-8 来说这却是不可能的,因为 UTF-8 字节序列具有不允许任意字节序列的特别结构。 为了提升 UTF-8 编码格式检测的可靠性,Microsoft 发明了一种 UTF-8 的变体形式 (Python 称之为 "utf-8-sig"
) 专门用于其 Notepad 程序:在任何 Unicode 字节被写入文件之前,会先写入一个 UTF-8 编码的 BOM (它看起来是这样一个字节序列: 0xef
, 0xbb
, 0xbf
)。 由于任何字符映射编码后的文件都不大可能以这些字节值开头 (例如它们会映射为
标准编码
Python 自带了许多内置的编解码器,它们的实现或者是通过 C 函数,或者是通过映射表。 以下表格是按名称排序的编解码器列表,并提供了一些常见别名以及编码格式通常针对的语言。 别名和语言列表都不是详尽无遗的。 请注意仅有大小写区别或使用连字符替代下划线的拼写形式也都是有效的别名;因此,'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
ascii
646, us-ascii
big5-tw, csbig5
big5hkscs
big5-hkscs, hkscs
cp037
IBM037, IBM039
cp273
273, IBM273, csIBM273
Added in version 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
Added in version 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
euc_jp
eucjp, ujis, u-jis
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
chinese, csiso58gb231280,
euc-cn, euccn, eucgb2312-cn,
gb2312-1980, gb2312-80,
iso-ir-58
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, cyrillic
保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语
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, thai
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
Added in version 3.5.
koi8_u
kz1048
kz_1048, strk1048_2002, rk1048
Added in version 3.5.
mac_cyrillic
maccyrillic
保加利亚语,白俄罗斯语,马其顿语,俄语,塞尔维亚语
mac_greek
macgreek
mac_iceland
maciceland
mac_latin2
maclatin2, maccentraleurope,
mac_centeuro
中欧和东欧
mac_roman
macroman, macintosh
mac_turkish
macturkish
ptcp154
csptcp154, pt154, cp154,
cyrillic-asian
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, cp65001
utf_8_sig
在 3.4 版本发生变更: utf-16* 和 utf-32* 编码器将不再允许编码代理码位 (U+D800
--U+DFFF
)。 utf-32* 解码器将不再解码与代理码位相对应的字节序列。
在 3.8 版本发生变更: cp65001
现在是 utf_8
的一个别名。
Python 专属的编码格式
有一些预定义编解码器是 Python 专属的,因此它们在 Python 之外没有意义。 这些编解码器按其所预期的输入和输出类型在下表中列出(请注意虽然文本编码是编解码器最常见的使用场景,但下层的编解码器架构支持任意数据转换而不仅是文本编码)。 对于非对称编解码器,该列描述的含义是编码方向。
文字编码
以下编解码器提供了 str
到 bytes
的编码和 bytes-like object 到 str
的解码,类似于 Unicode 文本编码。
实现 RFC 3490,另请参阅 encodings.idna
。仅支持 errors='strict'
。
ansi,
Windows 专属:根据 ANSI 代码页(CP_ACP)对操作数进行编码。
Windows 专属:根据 OEM 代码页(CP_OEMCP)对操作数进行编码。
Added in version 3.6.
palmos
PalmOS 3.5 的编码格式
punycode
实现 RFC 3492。 不支持有状态编解码器。
raw_unicode_escape
Latin-1 编码格式附带对其他码位以 \uXXXX
和 \UXXXXXXXX
进行编码。 现有的反斜杠不会以任何方式转义。 它被用于 Python 的 pickle 协议。
undefined
所有转换都将引发异常,甚至对空字符串也不例外。 错误处理方案会被忽略。
unicode_escape
适合用于以 ASCII 编码的 Python 源代码中的 Unicode 字面值内容的编码格式,但引号不会被转义。 对 Latin-1 源代码进行解码。 请注意 Python 源代码实际上默认使用 UTF-8。
二进制转换
以下编解码器提供了二进制转换: bytes-like object 到 bytes
的映射。 它们不被 bytes.decode()
所支持(该方法只生成 str
类型的输出)。
编码器/解码器
base64_codec
base64, base_64
将操作数转换为多行 MIME base64 (结果总是包含一个末尾的 '\n'
)
在 3.4 版本发生变更: 接受任意 bytes-like object 作为输入用于编码和解码
base64.encodebytes()
/
base64.decodebytes()
bz2_codec
使用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
使用uuencode转换操作数
uu.encode()
/ uu.decode()
(注意: uu
已被弃用。)
zlib_codec
zip, zlib
使用gzip压缩操作数
zlib.compress()
/
zlib.decompress()
此模块实现了 RFC 3490 (应用程序中的国际化域名) 和 RFC 3492 (Nameprep: 用于国际化域名 (IDN) 的 Stringprep 配置文件)。 它是在 punycode
编码格式和 stringprep
的基础上构建的。
如果你需要来自 RFC 5891 和 RFC 5895 的 IDNA 2008 标准,请使用第三方的 idna 模块。
这些 RFC 共同定义了一个在域名中支持非 ASCII 字符的协议。 一个包含非 ASCII 字符的域名 (例如 www.Alliancefrançaise.nu
) 会被转换为兼容 ASCII 的编码格式 (简称 ACE,例如 www.xn--alliancefranaise-npb.nu
)。 随后此域名的 ACE 形式可以用于所有由于特定协议而不允许使用任意字符的场合,例如 DNS 查询,HTTP 字段等等。 此转换是在应用中进行的;如有可能将对用户可见:应用应当透明地将 Unicode 域名标签转换为线上的 IDNA,并在 ACE 标签被呈现给用户之前将其转换回 Unicode。
Python 以多种方式支持这种转换: idna
编解码器执行 Unicode 和 ACE 之间的转换,基于在 section 3.1 of RFC 3490 中定义的分隔字符将输入字符串拆分为标签,再根据需要将每个标签转换为 ACE,相反地又会基于 .
分隔符将输入字节串拆分为标签,再将找到的任何 ACE 标签转换为 Unicode。 此外,socket
模块可透明地将 Unicode 主机名转换为 ACE,以便应用在将它们传给 socket 模块时无须自行转换主机名。 除此之外,许多包含以主机名作为函数参数的模块例如 http.client
和 ftplib
都接受 Unicode 主机名(并且 http.client
也会在 字段中透明地发送 IDNA 主机名,如果它需要发送该字段的话)。
当从线路接收主机名时(例如反向名称查找),到 Unicode 的转换不会自动被执行:希望向用户提供此种主机名的应用应当将它们解码为 Unicode。
encodings.idna
模块还实现了 nameprep 过程,该过程会对主机名执行特定的规范化操作,以实现国际域名的大小写不敏感特性与合并相似的字符。 如果有需要可以直接使用 nameprep 函数。
encodings.idna.nameprep(label)