ChatGPT解决这个技术问题 Extra ChatGPT

编码/解码有什么区别?

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

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

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

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

编辑:

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

我认为this page的第二个答案足够清晰和简洁。

佚名

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 类型,这不再是一个问题。


Unicode 字符串上的 .decode() 可能有用,例如,print u'\\u0203'.decode('unicode-escape')
python3中@JFSebastian的好例子我猜你会这样做: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:您的第一条评论(为什么要删除它?不要删除已回复的评论)已经说过了。我的回复 (.encode('ascii').decode('unicode-escape')) 不依赖于 sys.getdefaultencoding()
c
codeape

将 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 和字符集的绝对最低要求(没有借口!)

统一码如何


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

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 和字符串。


n
nosklo

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 之间进行正确的编码/解码时,无论如何这看起来都是一团糟。


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

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

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

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

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

而计算机将中文写入计算机内存的过程是encode()

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