如何处理“UnicodeEncodeError:'ascii'编解码器不能编码字符u'\ u2019'”?

时间:2016-06-22 18:00:44

标签: python python-2.7 unicode encoding utf-8

我正在尝试使用Python 2.7模块adodbapi访问SQL Server上的表,并将某些信息打印到命令提示符(Windows)。这是我的原始代码段:

query_str = "SELECT id, headline, state, severity FROM GPS3.Defect ORDER BY id"

cur.execute(query_str)
dr_data = cur.fetchall()
con.close()

for i in dr_data:
    print i

它将打印出大约30行,所有格式都正确,但它会停止并给我这个:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 52: oridinal not in range(128)

所以我在网上查看了这篇文章,并通过演示文稿解释了Python中的Unicode,我认为我明白了。所以我会明确告诉Python 解释它正在处理Unicode,并应将其编码为UTF-8。 这就是我想出的:

for i in dr_data:
    print (u"%s"%i).encode('utf-8')

但是,我想我实际上并不理解Unicode,因为我在运行时遇到了同样的错误。我知道这个问题很多,但有人可以向我解释,简单地说,这里发生了什么?提前谢谢。

1 个答案:

答案 0 :(得分:0)

您的错误消息与您在Windows命令提示符下打印的语句不一致。它不默认为ascii编解码器。在美国Windows上,默认为cp437

您只需将Unicode打印到控制台,而无需对其进行编码。 Python会将Unicode字符串编码为控制台编码。这是一个例子。请注意,源文件以UTF-8编码保存,并使用特殊#coding:utf8注释声明编码。这允许任何Unicode字符都在源代码中。

#coding:utf8
s1 = u'αßΓπΣσµτ'    # cp437-supported
s2 = u'ÀÁÂÃÄÅ'      # cp1252-supported
s3 = u'我是美国人。' # unsupported by cp437 or cp1252.

由于我的美国Windows控制台默认为cp437,因此只会显示s1而不会出错。

C:\>chcp
Active code page: 437

C:\>py -2 -i test.py
>>> print s1
αßΓπΣσµτ
>>> print s2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-3: character maps to <undefined>
>>> print s3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-5: character maps to <undefined>

请注意,错误消息表明它尝试使用的编码:cp437

如果我更改控制台编码,现在s2将正常运行:

C:\>chcp 1252
Active code page: 1252

C:\>py -2 -i test.py
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u03b1' in position 0: character maps to <undefined>
>>> print s2
ÀÁÂÃÄÅ
>>> print s3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-5: character maps to <undefined>

现在s3包含常见西方编码不支持的字符。您可以进入控制面板并将系统区域设置更改为中文,然后控制台将支持中文编码,但更好的解决方案是使用支持UTF-8的Python IDE,这是一种支持所有Unicode字符的编码(受字体支持)或者当然)。下面是PythonWin的输出,这是一个带有pywin32 Python扩展的编辑器:

>>> print s1
αßΓπΣσµτ
>>> print s2
ÀÁÂÃÄÅ
>>> print s3
我是美国人。

总之,只使用Unicode字符串,理想情况下使用UTF-8的终端,它将“正常工作”。一旦从文件,用户输入,网络套接字等读取文本数据,就将其转换为Unicode。以Unicode格式处理和打印,但在离开程序时对其进行编码(写入文件,网络套接字等)。