理解 decode() 和 encode() unicode

understanding decode() and encode() unicode

我只是不明白函数 decode()encode() 如何在 python2.7

上工作

我尝试了以下语句

>>> s = u'abcd'
>>> s.encode('utf8')
'abcd'
>>> s.encode('utf16')
'\xff\xfea\x00b\x00c\x00d\x00'
>>> s.encode('utf32')
'\xff\xfe\x00\x00a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00d\x00\x00\x00'

到此为止,我想已经很清楚了; encode() 在相应的 utf-8/16/32 字节字符串中翻译一个 unicode 代码。

但是当我编码时:

>>> s.decode('utf8')
u'abcd'
>>> s.decode('utf16')
u'\u6261\u6463'
>>> s.decode('utf32')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/utf_32.py", line 11, in decode
    return codecs.utf_32_decode(input, errors, True)
UnicodeDecodeError: 'utf32' codec can't decode bytes in position 0-3: codepoint not in range(0x110000)

为什么 decode() 的意思是在 unicode 类型上?为什么第一个(使用 utf8)工作而不是后者?是因为 python 内部使用 utf-8 存储 unicode 字符串吗?

最后一件事:

>>> s2 = '≈'
>>> s2
'\xe2\x89\x88'

引擎盖下发生了什么? '≈' 不是 ascii 字符,因此 python 使用编码 sys.getfilesystemencoding() returns?

隐式转换它

您正在 unicode 字符串上调用 decode。 Python 首先使用默认的 ASCII 编解码器 编码 字符串,这样您就可以对 的实际字节进行解码。您无法解码 Unicode 数据本身,它 已经 解码。

解码失败,因为字节不是有效的 UTF-32 数据。 bytestring 'abcd' 可解码为 UTF-8,因为 ASCII 是 UTF-8 的子集。编码为 ASCII,然后解码为 UTF-8 会产生相同的信息。解码为 UTF-16 碰巧成功了;您提供了 4 个十六进制值 0x61、0x62、0x63 和 0x64 的字节(字符 abcd 的 ASCII 值),这些字节可以解码为 \u6261 和 [=17 的 UTF-16 little endian =].但是在UTF-32编码系统中,这4个字节没有有效的解码。

如果 s 中的数据无法首先编码为 ASCII,您将得到一个 UnicodeEncodeError 异常;请注意该名称中的 Encode

>>> u'åßç'.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mj/Development/venvs/Whosebug-2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

因为对字节串的隐式编码失败。

在 Python 3 中,unicode 对象已重命名为 str,并且已从类型中删除 str.decode() 方法以防止这种混淆。只剩下 str.encode()。 Python str 类型已被 bytes 类型取代,后者只有一个 bytes.decode() 方法。

您的第二个示例表明您正在终端或控制台中以交互方式使用 Python 解释器。 Python 从终端以 UTF-8 字节形式接收您的输入,并将这些字节存储在字节串中。如果您使用 unicode 文字,Python 会使用为您的终端声明的编码自动解码这些字节;您可以内省 sys.stdin.encoding 以查看 Python 检测到的内容:

>>> import sys
>>> sys.stdin.encoding
'UTF-8'
>>> s = '≈'
>>> s
'\xe2\x89\x88'
>>> s = u'≈'
>>> s
u'\u2248'
>>> print s
≈

反之亦然,打印时 sys.stdout.encoding 编解码器用于将 Unicode 字符串自动编码为终端使用的编解码器,然后再次解释这些字节以在屏幕上显示正确的字形。

如果您不在 Python 交互式解释器中工作,而是在使用 Python 源文件,则要使用的编解码器由 PEP-263 Python source code encodings declaration 决定,如 Python 2 否则默认将字节解码为 ASCII。

sys.getfilesystemencoding()与这一切无关;它告诉你 Python 认为你的 文件系统元数据 是用什么编码的;例如目录中的文件名。当您使用 unicode 路径进行与文件系统相关的调用(如 os.listdir().

时,将使用这些值