为什么 Python 2 允许对字符串对象使用 .encode()?

Why does Python 2 allow .encode() on string objects?

在Python2中,可以调用str.decode得到一个unicode对象,unicode.encode得到一个str对象。

>>> "foo".decode('utf-8')
u'foo'
>>> u"foo".encode('utf-8')
'foo'

Python3类似,用bytes.decode得到一个字符串,str.encode得到一个bytes对象

>>> "foo".encode('utf-8')
b'foo'
>>> b"foo".decode('utf-8')
'foo'

但是,Python 2(但不是 Python 3)也提供了错误的方法:您可以在 str 对象上调用 .encode,或者 .decode 在 unicode 对象上!

>>> "foo".encode('utf-8')
'foo'
>>> u"foo".decode('utf-8')
u'foo'

这是为什么?有没有什么时候在 unicode 对象上调用 .decode 有用,反之亦然?

因为在 Python 2 中,您希望透明地互换地处理字节字符串(str 对象)和 Unicode 字符串(unicode 对象)中的文本。当期望字节串时,unicode 对象被透明编码(ASCII),相反,当期望 Unicode 时,str 对象被透明解码,再次假设为 ASCII。

所以str.encode()会先解码,然后再编码。或者 unicode.decode() 将首先 编码 ,然后解码结果。

只有当您的代码想要接受 strunicode 对象并可互换地处理它们时,才有用。因此,期望字节串并尝试解码该字节串的函数将继续工作,即使您传入仅包含 ASCII 代码点的 unicode 对象。

这导致了大量的混乱和错误(只需在 Stack Overflow 上搜索 UnicodeEncodeErrorUnicodeDecodeError),所以在 Python 3 中,类型是 dis-entangled.