编码/解码有啥区别?

Posted

技术标签:

【中文标题】编码/解码有啥区别?【英文标题】:What is the difference between encode/decode?编码/解码有什么区别? 【发布时间】:2010-10-01 14:50:54 【问题描述】:

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

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

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

但我不明白str().encode()unicode().decode() 是干什么用的。任何人都可以解释,并可能纠正我在上面弄错的任何其他内容吗?

编辑:

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

【问题讨论】:

我觉得this page的第二个回答已经够清晰简洁了。 【参考方案1】:

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

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()也是多余的。

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

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

不过,您是对的:对于这两个应用程序,“编码”的模棱两可的用法是……很尴尬。同样,在 Python 3 中使用单独的 bytestring 类型,这不再是问题。

【讨论】:

.decode() 在 Unicode 字符串上可能有用,例如 print u'\\u0203'.decode('unicode-escape') python3 中@J.F.Sebastian 的好例子我猜你会这样做:print u'\\u0203'.encode('utf8').decode('unicode-escape') @AJP:在 Python 3 上:codecs.decode(u'\\u0203', 'unicode-escape') @hop:是的。为了检测无效输入和 Python 2/3 兼容性,可以使用 ascii 编码显式编码字符串:\\u0203\u00e4'.encode('ascii').decode('unicode-escape') @hop:您的第一条评论(为什么要删除它?不要删除已回复的cmets)已经说过了。我的回复(.encode('ascii').decode('unicode-escape'))不依赖于sys.getdefaultencoding()【参考方案2】:

将 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”编解码器无法对位置 0-5 中的字符进行编码: 序数不在范围内(128)

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

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

例子:

>>> u'æøå' u'\xc3\xa6\xc3\xb8\xc3\xa5' # 解释器像这样打印 unicode 对象 >>> unicode('\xc3\xa6\xc3\xb8\xc3\xa5', 'latin1') 你'\xc3\xa6\xc3\xb8\xc3\xa5' >>> '\xc3\xa6\xc3\xb8\xc3\xa5'.decode('latin1') 你'\xc3\xa6\xc3\xb8\xc3\xa5'

当您从网络或磁盘文件接收到字符串数据时,您通常会解码一串字节。

我相信 python 3 中的 unicode 处理有一些变化,所以上述对于 python 3 可能不正确。

一些不错的链接:

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) Unicode HOWTO

【讨论】:

您没有回答 OP 的问题。 OP 想知道 str.encode() 和 unicode.decode() 做什么。您只是重复了原始问题中所述的内容。 很好的答案,为什么在实践中你会搞乱解码和编码。不是每台机器都理解相同的字符集,但它们都理解字节。将计算机普遍理解的语言编码为字节(并且可以传输或保存到磁盘),但在人类实际必须读取这些字节时(例如在客户端)进行解码。 绝妙的答案!这应该上升!【参考方案3】:

anUnicode.encode('encoding') 产生一个 string 对象,并且可以在 unicode 对象上调用

aString.decode('encoding') 产生一个 unicode 对象,并且可以在字符串上调用,以给定的编码进行编码。


更多解释:

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

但是有一段时间,您希望将 unicode 对象打印到控制台或某个文本文件中。所以你必须encode它(例如 - 在 UTF-8 中),你调用 encode('utf-8') 并且你会得到一个包含 '\u' 的字符串,即完美打印。

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

顺便说一句 - 您可以选择一些变态编码,例如“zip”、“base64”、“rot”,其中一些会从字符串转换为字符串,但我相信最常见的情况是涉及UTF-8/UTF-16 和字符串。

【讨论】:

【参考方案4】:

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

base64 bz2 zlib 十六进制 quopri rot13 string_escape uu

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

【讨论】:

【参考方案5】:

有一些编码可用于从 str 到 str 或从 unicode 到 unicode 进行解码/编码。例如 base64、hex 甚至 rot13。它们在codecs module 中列出。

编辑:

对一个unicode字符串的decode消息可以撤销对应的encode操作:

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

返回的类型是 str 而不是 unicode,这在我看来是不幸的。但是,当您没有在 str 和 unicode 之间进行适当的编码/解码时,这看起来还是一团糟。

【讨论】:

-1:解码方法未应用于 unicode 对象。相反,在解码操作开始之前,unicode 对象被编码为“ascii”字节串。要证明该断言,请尝试 u'ã'.decode('hex') - 产生 UnicodeEncodeError @nosklo:你是对的。我真正的意思是 unicode 对象具有 decode() 方法,因此您也可以将非字符编码编解码器应用于它们。这整个非字符编码业务使这个接口在 Python 中变得一团糟 【参考方案6】:

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

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

例如,'\xe4\xb8\xad\xe6\x96\x87'是两个汉字的表示,但是计算机只有在给定字典时才知道(即打印或存储)是汉字查找那个中文单词,在这种情况下,它是一个“utf-8”字典,如果您查看不同或错误的字典(使用不同的解码方法),它将无法正确显示预期的中文单词。

在上述情况下,计算机查找中文单词的过程是decode()

而电脑将中文写入电脑内存的过程是encode()

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

【讨论】:

以上是关于编码/解码有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

编解码mpeg4和xvid有啥区别?

escape,encodeURI,encodeURIComponent有啥区别

格式工厂DIVX、AVC、HEVC三个格式那个最清晰?那个压缩出来小?有啥区别?

decoder 和coder 在英语解释及用法方面啥区别,还有从计算机用法上面有啥区别?

高清格式X264和H264有啥区别

条码扫描枪与手机条码扫描枪有啥区别