当我无法事先知道char编码时,如何打印字符串列表?

时间:2010-09-06 16:00:28

标签: python encoding

我正在使用我用Python编写的客户端从Web服务中检索名称列表。检索列表后,我将每个名称编码为unicode,然后将每个名称打印到stdout。当我得到“ÓlafurJóhannÓlafsson”这个名字时,我收到以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: 
                    ordinal not in range(128)

由于我不知道编码是什么,如何将所有这些字符串转换为unicode?或者你能建议一个更好的方法来处理这个问题吗?

3 个答案:

答案 0 :(得分:1)

来自BeautifulSoupUnicodeDammit模块可以自动检测编码。

from BeautifulSoup import UnicodeDammit

u = UnicodeDammit("Ólafur Jóhann Ólafsson")

print u.unicode
print u.originalEncoding

答案 1 :(得分:1)

此页面可能会对您有所帮助http://wiki.python.org/moin/PrintFails

问题,我想,你需要将这些名称打印到控制台。你真的需要它吗?或者它只是一个测试环境?如果您仅使用控制台进行测试,您可以切换到其他工具,如单元测试,以检查您确切获得的值。

答案 2 :(得分:1)

首先,从文件,管道,套接字,终端等读取时,解码数据到Unicode(编码的缺席);发送/保存数据时,将编码 Unicode编码为适当的字节编码。我怀疑这是你问题的根源。

Web服务应在收到的标头或数据中声明编码。 print通常会自动将Unicode编码为终端的编码(通过sys.stdout.encoding发现)或仅在ascii时没有编码。如果目标编码不支持数据中的字符,您将获得UnicodeEncodeError

由于这不是您收到的错误,您应该发布一些代码,以便我们可以看到您在做什么。最有可能的是,您编码一个字节字符串而不是解码。这是一个例子:

>>> data = '\xc2\xbd' # UTF-8 encoded 1/2 symbol.
>>> data.encode('cp437')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\dev\python\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)

我在这里做的是在字节字符串上调用encode。由于encode需要Unicode字符串,因此在编码为ascii之前,Python首先使用默认的cp437编码将字节字符串解码为Unicode。

通过解码而不是编码数据来解决此问题,然后print将自动编码为stdout。只要您的终端支持数据中的字符,它就会正确显示:

>>> import sys
>>> sys.stdout.encoding
'cp437'
>>> print data.decode('utf8') # implicit encode to sys.stdout.encoding
½
>>> print data.decode('utf8').encode('cp437') # explicit encode.
½