理解 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()
.
时,将使用这些值
我只是不明白函数 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()
.