关于python:编码/解码有什么区别?encode/decode

What is the difference between encode/decode?

我从未确定我理解str/unicode解码和编码之间的区别。

我知道str().decode()是用来当你有一个字节串,你知道它有一个特定的字符编码,给定编码名,它将返回一个unicode字符串。

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

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

编辑:

几个答案给出了有关.encode在字符串上的作用的信息,但似乎没有人知道.decode在Unicode上的作用。


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

unicode().decode()将使用默认(ASCII)编解码器执行s的隐式编码。这样验证:

1
2
3
4
5
6
7
8
9
10
11
12
>>> 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

1
2
3
4
5
6
7
8
>>> 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位字符串:

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

不过,您是对的:这两个应用程序的"编码"用法不明确是…笨拙。同样,在Python3中使用单独的bytestring类型,这不再是一个问题。


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

例子:

1
2
3
4
5
6
7
    >>> 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)或"…"解码(编码)。

例子:

1
2
3
4
5
6
   >>> 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和字符集(没有借口!)
  • Unicode WHOTO


anunicode.encode("encoding")生成一个字符串对象,可以在Unicode对象上调用。

decode("encoding")产生一个unicode对象,可以对以给定编码编码的字符串调用。

更多解释:

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

但有一段时间,当您想将Unicode对象打印到控制台或某个文本文件中时。因此,您必须对其进行编码(例如,使用utf-8),然后调用encode("utf-8"),您将得到一个字符串,该字符串内有"u",这是完全可打印的。

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

正如附带说明-您可以选择一些不正常的编码,如"zip"、"base64"、"rot",其中一些编码将从字符串转换为字符串,但我认为最常见的情况是涉及utf-8/utf-16和字符串的编码。


mybytestring.encode(somecodec)对于somecodec的这些值很有意义:

  • Base64
  • BZ2
  • ZLIB
  • 十六进制
  • 夸普里
  • 罗13
  • 纵梁逃生
  • UU

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


你应该阅读python unicodedecodeerror-我误解了编码吗?在阅读了公认的答案之后,我对Python中Unicode的理解更加清晰了。


有一些编码可以用于从str到str或从unicode到unicode的去/编码。例如base64、hex甚至rot13。它们列在编解码器模块中。

编辑:

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

1
2
3
In [1]: u'0a'.decode('hex')
Out[1]: '
'

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


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

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

例如,"xe4xb8xadxe6x96x87"是两个汉字的表示,但计算机只知道(即打印或存储)当它们被赋予一个字典来查找那个汉字时,它是汉字,在这种情况下,它是"utf-8"字典,如果您查找它,它将无法正确显示预期的汉字。不同或错误的字典(使用不同的解码方法)。

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

计算机将汉字写入计算机存储器的过程是编码的。

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