我一直不确定我是否理解 str/unicode 解码和编码之间的区别。
我知道 str().decode()
用于当您有一个知道具有特定字符编码的字节字符串时,考虑到该编码名称,它将返回一个 unicode 字符串。
我知道 unicode().encode()
根据给定的编码名称将 unicode 字符转换为字节串。
但我不明白 str().encode()
和 unicode().decode()
是干什么用的。任何人都可以解释,并可能纠正我在上面弄错的任何其他内容吗?
编辑:
有几个答案提供了有关 .encode
对字符串的作用的信息,但似乎没有人知道 .decode
对 unicode 的作用。
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
类型,这不再是一个问题。
将 unicode 字符串表示为字节字符串称为 encoding。使用 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(encoding)。
例子:
>>> 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'
每当您从网络或磁盘文件接收到字符串数据时,您通常会解码一串字节。
我相信 python 3 中的 unicode 处理有一些变化,所以上述对于 python 3 可能不正确。
一些很好的链接:
每个软件开发人员绝对、绝对必须了解 Unicode 和字符集的绝对最低要求(没有借口!)
统一码如何
anUnicode.encode('encoding') 产生一个字符串对象,可以在 unicode 对象上调用
aString.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
十六进制
夸普里
rot13
string_escape
你
我不确定解码已经解码的 unicode 文本有什么好处。尝试使用任何编码似乎总是首先尝试使用系统的默认编码进行编码。
有一些编码可用于从 str 到 str 或从 unicode 到 unicode 进行解码/编码。例如 base64、hex 甚至 rot13。它们列在 codecs module 中。
编辑:
unicode 字符串上的解码消息可以撤消相应的编码操作:
In [1]: u'0a'.decode('hex')
Out[1]: '\n'
返回的类型是 str 而不是 unicode,这在我看来是不幸的。但是,当您没有在 str 和 unicode 之间进行正确的编码/解码时,无论如何这看起来都是一团糟。
简单的答案是它们彼此完全相反。
计算机使用最基本的字节单位来存储和处理信息;对人眼来说是没有意义的。
例如,'\xe4\xb8\xad\xe6\x96\x87' 是两个汉字的表示,但是计算机只有在给定字典来查找时才知道(意味着打印或存储)它是汉字中文单词,在这种情况下,它是一个“utf-8”字典,如果您查看不同或错误的字典(使用不同的解码方法),它将无法正确显示预期的中文单词。
在上述情况下,计算机查找中文单词的过程是decode()
。
而计算机将中文写入计算机内存的过程是encode()
。
所以编码信息是原始字节,解码信息是原始字节和要引用的字典的名称(但不是字典本身)。
不定期副业成功案例分享
.decode()
可能有用,例如,print u'\\u0203'.decode('unicode-escape')
print u'\\u0203'.encode('utf8').decode('unicode-escape')
codecs.decode(u'\\u0203', 'unicode-escape')
ascii
编码对字符串进行显式编码:\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
.encode('ascii').decode('unicode-escape')
) 不依赖于sys.getdefaultencoding()
。