我明白了有关 unicode、编码和解码的要点。但我不明白为什么
encode()
函数适用于字符串对象。我预计它只能在 unicode 类型上工作。
当
encode()
用于字符串对象而不是 unicode 对象时,它的行为是什么?
在 Python 2 中,有两种类型的编解码器可用;那些在
str
和 unicode
之间转换的,以及那些从 str
转换到 str
的。后者的示例是 base64
和 rot13
编解码器。
str.encode()
方法的存在是为了支持后者:
'binary data'.encode('base64')
但现在它已经存在,人们也将它用于
unicode
-> str
编解码器;编码只能从 unicode
到 str
(解码则相反)。为了支持这些,Python 将首先使用 ASCII 编解码器隐式将您的 str
值解码为 unicode
,然后再进行最终编码。
顺便说一句,当在
str
对象上使用 str
-> unicode
编解码器时,Python 首先使用相同的 ASCII 编解码器隐式编码为 str
。
在 Python 3 中,这个问题已通过以下方法解决:a) 删除
bytes.encode()
和 str.decode()
方法(请记住,bytes
是旧的 str
和 str
新的 unicode
),以及 b) 通过使用 str
和 str
函数将 codecs
->
codecs.encode()
编码移动到 codecs.decode()
模块only。相同类型之间的编解码器转换也已得到澄清和更新,请参阅Python 特定编码部分;请注意,此处注明的“文本”编码(在 Python 2 中可用)会编码为
str
。
Python 意识到它无法对
encode
类型执行 str
,因此它首先尝试对其进行 decode
! 它使用 'ascii'
编解码器,如果您有任何代码点高于 0x7f 的字符,该编解码器将会失败。
这就是为什么当您尝试执行
decode
时有时会看到出现 encode
错误。
在 Python 3 中,对字节串进行编码根本不起作用。
>>> b'hi'.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'bytes' object has no attribute 'encode'
当您在 encode
上调用 str
并首先尝试使用
sys.getdefaultencoding()
(通常为 ascii)对字符串进行解码,然后随后
对其进行编码时,Python 2 尝试会很有帮助。
这就是为什么当您尝试使用 utf-8 进行编码时,您会收到相当奇怪的错误消息:无法使用 ascii 进行解码。
>>> 'hi\xFF'.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 2: ordinal not in range(128)
Ned 解释得比我好,请从 16:20 开始观看this。