编码/解码的区别是什么?

我从来不确定自己是否理解 str/unicode 解码和编码之间的区别。

我知道当你有一个字节串,你知道有一个特定的字符编码,给定的编码名称,它将返回一个 unicode 字符串。

我知道 unicode().encode()根据给定的编码名称将 unicode 字符转换为字节串。

但是我不明白 str().encode()unicode().decode()是用来干什么的。有没有人能解释一下,也许还能纠正一下我上面所说的其他错误?

编辑:

有几个答案提供了关于 .encode对字符串做什么的信息,但似乎没有人知道 .decode对 unicode 做什么。

112484 次浏览

有一些编码可用于从 str 到 str 或从 unicode 到 unicode 的解/编码。例如 base64、十六进制甚至 rot13。他们被列入 译码器模块译码器模块

编辑:

Unicode 字符串上的解码消息可以撤消相应的编码操作:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

返回的类型是 str 而不是 unicode,在我看来这很不幸。但是,当您在 str 和 unicode 之间不进行正确的 en-/decode 时,无论如何这看起来都是一团糟。

Encode (somecodec)对于 somecodec的这些值是有意义的:

  • 基地64
  • Bz2
  • Zlib
  • 巫术
  • Quopri
  • Rot13
  • String _ escape

我不确定对已经解码的 Unicode 文本进行解码有什么好处。尝试使用任何编码似乎总是尝试首先使用系统的默认编码进行编码。

将 unicode 字符串表示为字节字符串称为 编码。使用 u'...'.encode(encoding)

例如:

>>> u'æøå'.encode('utf8')
'\xc3\x83\xc2\xa6\xc3\x83\xc2\xb8\xc3\x83\xc2\xa5'
>>> u'æøå'.encode('latin1')
'\xc3\xa6\xc3\xb8\xc3\xa5'
>>> u'æøå'.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5:
ordinal not in range(128)

每当需要将 Unicode 字符串用于 IO 时,通常都要对其进行编码,例如通过网络传输它,或者将它保存到磁盘文件中。

要将字节串转换为 unicode 字符串,称为 解码。请使用 unicode('...', encoding)或“ ...”. decode (编码)。

例如:

>>> u'æøå'
u'\xc3\xa6\xc3\xb8\xc3\xa5' # the interpreter prints the unicode object like so
>>> unicode('\xc3\xa6\xc3\xb8\xc3\xa5', 'latin1')
u'\xc3\xa6\xc3\xb8\xc3\xa5'
>>> '\xc3\xa6\xc3\xb8\xc3\xa5'.decode('latin1')
u'\xc3\xa6\xc3\xb8\xc3\xa5'

每当从网络或磁盘文件接收字符串数据时,通常都要解码一个字节字符串。

我相信在 python3中 unicode 处理有一些变化,因此上面的内容可能不适用于 python3。

一些好的链接:

Unicode 字符串的 decode方法实际上根本没有任何应用程序(除非由于某种原因在 unicode 字符串中包含一些非文本数据——见下文)。我认为这主要是出于历史原因。在 Python3中,它完全消失了。

unicode().decode()将使用默认(ascii)编解码器执行 s的隐式 编码:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)


>>> s.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

错误消息完全相同。

对于 str().encode(),情况恰恰相反——它尝试使用默认编码方式隐式地使用 s解码:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

像这样使用,str().encode()也是多余的。

但是 后一种方法的另一个应用是有用的: 编码与字符集无关,因此可以以一种有意义的方式应用于8位字符串:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

不过,您是对的: 对于这两个应用程序来说,“编码”这种模棱两可的用法是... ... 尴尬的。同样,在 Python3中使用单独的 bytestring类型时,这不再是一个问题。

编码(‘ coding’)生成一个 绳子对象,可以对 unicode 对象调用它

解码(‘ coding’)产生一个 Unicode对象,并且可以对一个字符串进行调用,该字符串以给定的编码进行编码。


更多解释:

您可以创建一些 unicode 对象,它没有任何编码集。Python 在内存中存储它的方式与您无关。您可以搜索它,分割它,并调用任何字符串操作函数,您喜欢。

但是有时候,您希望将 unicode 对象打印到控制台或某个文本文件中。所以你必须对它进行 编码(例如,在 UTF-8中) ,调用 encode (‘ UTF-8’) ,得到一个字符串,其中包含‘ u < some Number >’,这是完全可以打印的。

然后,再一次-您希望执行用 UTF-8编码的反向读取字符串,并将其视为 Unicode,因此 u360将是一个字符,而不是5。然后使用 解码字符串(使用选定的编码)并获得 unicode 类型的全新对象。

顺便说一句,你可以选择一些变态编码,比如‘ zip’、‘ base64’、‘ rot’,其中一些会从字符串转换成字符串,但我相信最常见的情况是包含 UTF-8/UTF-16和字符串的情况。

简单的答案是,它们彼此完全相反。

计算机使用最基本的字节单位来存储和处理信息,对人眼来说毫无意义。

例如,‘ xe4 xb8 xad xe6 x96 x87’是两个中文字符的表示,但计算机只知道(意味着打印或存储)它是中文字符时,他们被给予一个字典来查找该中文字,在这种情况下,它是一个“ utf-8”字典,它将不能正确显示预期的中文字符,如果你查找不同的或错误的字典(使用不同的解码方法)。

在上面的例子中,计算机查找中文单词的过程是 decode()

计算机将汉语写入计算机存储器的过程是 encode()

所以编码的信息是原始字节,解码的信息是原始字节和要引用的字典(但不是字典本身)的名称。