Linux/Python: 编码Unicode字符串以供打印
我有一个比较大的 Python 2.6 应用程序,里面到处都是打印语句。我使用的是 Unicode 字符串,通常运行得很好。不过,如果我把程序的输出重定向到文件里(比如用 "myapp.py >output.txt"),有时会出现这样的错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa1' in position 0: ordinal not in range(128)
我猜如果有人把他们的 LOCALE 设置成 ASCII,也会遇到同样的问题。其实我完全明白这个错误的原因。我的 Unicode 字符串里有些字符是不能用 ASCII 编码的,这没问题。但我希望我的 Python 程序能尽量打印出一些可理解的内容,可能跳过那些可疑的字符,或者用它们的 Unicode ID 来替代。
这个问题应该很常见……处理这个问题的最佳方法是什么呢?我希望能继续使用传统的 "print",但如果需要的话,我可以修改所有的地方。
附注:我现在已经解决了这个问题。 解决方案并不是给出的答案中的任何一个。我使用了在 http://wiki.python.org/moin/PrintFails 上提到的方法,这是 ChrisJ 在评论中提到的。也就是说,我用一个包装器替换了 sys.stdout,这个包装器调用 Unicode 编码并传入正确的参数。效果很好。
3 个回答
你可以通过一个方法来处理所有的打印语句,把任意的unicode字符转换成utf-8,或者如果没办法的话,可以在你的site.py文件里把Python的默认编码从ascii改成utf-8。一般来说,直接把unicode字符串不加处理地打印到系统输出(sys.stdout)上是个坏主意,因为Python会自动把unicode字符串转换成默认的编码,而这个默认编码是ascii。
如果你是在一个ASCII终端上输出内容,可以手动使用 unicode.encode
来进行编码,并且要指定忽略错误。
u = u'\xa0'
u.encode('ascii') # This fails
u.encode('ascii', 'ignore') # This replaces failed encoding attempts with empty string
如果你想保存unicode文件,可以试试这个:
u = u'\xa0'
print >>open('out', 'w'), u # This fails
print >>open('out', 'w'), u.encode('utf-8') # This is ok
我现在已经解决了这个问题。我的解决办法并不是之前给出的两个答案。我使用了在http://wiki.python.org/moin/PrintFails上提到的方法,这是ChrisJ在评论中提到的。具体来说,我用一个包装器替换了sys.stdout,这个包装器会用正确的参数调用unicode编码。效果非常好。