关于Python的Unicode – AM的误解:unicodedecodeerror编码?

Python UnicodeDecodeError - Am I misunderstanding encode?

有没有想过为什么这个不起作用?我真的认为"忽略"会做正确的事情。

1
2
3
4
>>> 'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
Traceback (most recent call last):
  File"<interactive input>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 4: ordinal not in range(128)

…他们被称为"编码"是有原因的…

有点序言:把Unicode看作是规范,或者理想状态。Unicode只是一个字符表。65是拉丁语大写A。937是希腊语大写Omega。就这样。

为了让计算机存储和操作Unicode,它必须将其编码为字节。Unicode最简单的编码是ucs-4;每个字符占用4个字节,所有~1000000个字符都可用。4个字节包含作为4字节整数的Unicode表中的字符数。另一个非常有用的编码是utf-8,它可以用一到四个字节对任何Unicode字符进行编码。但也有一些有限的编码,如"Latin1",其中包含的字符范围非常有限,大多数是西方国家使用的。这种编码每个字符只使用一个字节。

基本上,Unicode可以用许多编码进行编码,编码后的字符串可以解码为Unicode。问题是,Unicode出现得很晚,所以我们所有使用8位字符集长大的人都知道,我们处理编码字符串的时间太晚了。编码可以是ISO8859-1、Windows CP437或CP850,或者,或者,或者,或者,或者,取决于我们的系统默认值。

因此,当您在源代码中输入字符串"add"monitoring"to list"(我认为您希望字符串"add"monitoring"to list",请注意第二个引号),您实际上使用的是已经根据系统默认代码页编码的字符串(按字节x93,我假设您使用的是Windows代码页1252,"western")。如果要从中获得Unicode,则需要从"CP1252"编码中解码字符串。

所以,你想做的是:

1
"add \x93Monitoring\x94 to list".decode("cp1252","ignore")

不幸的是,python 2.x也为字符串包含了一个.encode方法;对于"特殊"编码来说,这是一个方便的函数,比如"zip"或"rot13"或"base64",这与unicode无关。

不管怎样,对于来回的Unicode转换,您需要记住的就是:

  • Unicode字符串被编码为python 2.x字符串(实际上是一个字节序列)
  • python 2.x字符串被解码为unicode字符串

在这两种情况下,都需要指定将使用的编码。

我不太清楚,我困了,但我希望我能帮忙。

附言:玛雅人没有Unicode,古罗马人,古希腊人,古埃及人也没有。他们都有自己的"编码",几乎不尊重其他文化。所有这些文明都化为灰烬。想想看,伙计们!让你的应用程序知道Unicode,为了人类的利益。:)

PS2请不要说"但是中文…"来破坏前面的信息。但是,如果你觉得有必要这样做,可以通过认为unicode BMP主要由汉字填充来延迟它,因此中文是unicode的基础。只要人们开发支持Unicode的应用程序,我就可以继续编造无耻的谎言。干杯!


encode可用于unicode字符串,但其中的字符串似乎不是unicode(请尝试使用u'addx93 monitoringx93 to list')

1
2
>>> u'add \x93Monitoring\x93 to list '.encode('latin-1','ignore')
'add \x93Monitoring\x93 to list '


我还写了一篇关于这个主题的长篇博客:

Unicode的麻烦和解决方法


遇到同样的问题;但是,在理解如何在不产生更多错误或无效语法错误的情况下适当地包含编码语法时遇到问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 genesis_block = {
    'hash': hash_function({
        'block_number': 0,
        'parent_hash': None,
        'transaction_count': 1,
        'transaction': [{'Tom': 10}]
    }),
    'contents': {
        'block_number': 0,
        'parent_hash': None,
        'transaction_count': 1,
        'transaction': [{'Tom': 10}]
    },
}

block_chain = [genesis_block]
chain_state = {'Tom': 10}

这似乎有效:

1
'add \x93Monitoring\x93 to list '.decode('latin-1').encode('latin-1')

有什么问题吗?我想知道"忽略"、"替换"和其他类似的编码错误处理何时出现?