编码/解码有啥区别?
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 中使用单独的 byte
和 string
类型,这不再是问题。
【讨论】:
.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
的这些值是有意义的:
我不确定解码已解码的 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()
。
所以编码信息是原始字节,解码信息是原始字节和要引用的字典的名称(但不是字典本身)。
【讨论】:
以上是关于编码/解码有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
escape,encodeURI,encodeURIComponent有啥区别
格式工厂DIVX、AVC、HEVC三个格式那个最清晰?那个压缩出来小?有啥区别?