python unicode处理print和sys.stdout.write之间的差异

Posted

技术标签:

【中文标题】python unicode处理print和sys.stdout.write之间的差异【英文标题】:python unicode handling differences between print and sys.stdout.write 【发布时间】:2011-12-22 09:46:51 【问题描述】:

我首先要说我已经看过这篇文章:Strange python print behavior with unicode,但是那里提供的解决方案(使用 PYTHONIOENCODING)对我不起作用。

这是我的问题:

Python 2.6.5 (r265:79063, Apr  9 2010, 11:16:46)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
>>> a = u'\xa6'
>>> print a 
¦

工作得很好,但是:

>>> sys.stdout.write(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa6' in position 0: ordinal not in range(128)

引发错误。我在顶部链接到的帖子表明这是因为默认控制台编码是“ascii”。但是,就我而言,它不是:

>>> sys.stdout.encoding
'UTF-8'

那么对这里的工作原理以及如何解决这个问题有什么想法吗?

谢谢 D.

【问题讨论】:

在带有 utf-8 终端编码的 python 2.7 上,一切似乎都正常。你能试试 sys.stdout.write(a.encode("UTF-8")) 看看会发生什么吗? 是的,那行得通...糟糕,我刚刚意识到我使用了错误的 Python 版本来生成示例。我应该使用 2.6.5。那么为什么会这样呢? 2.7 之前的 Python 中的错误? 显然,当尝试写入标准输出时,您的 Python 尝试使用 ascii 对您的 unicode 对象进行编码,但失败得很惨。我不知道为什么,但我的不这样做:) 【参考方案1】:

这是由于 python-2.7 中的一个长期存在的错误fixed,但为时已晚,无法向后移植到 python-2.6。

文档指出,当将 unicode 字符串写入文件时,应使用 file.encoding 将它们转换为字节字符串。但这并没有被 sys.stdout 尊重,而是使用默认的 unicode 编码。这通常由site 模块设置为“ascii”,但可以使用sys.setdefaultencoding 进行更改:

Python 2.6.7 (r267:88850, Aug 14 2011, 12:32:40) [GCC 4.6.2] on linux3
>>> a = u'\xa6\n'
>>> sys.stdout.write(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec cant encode character u'\xa6' ...
>>> reload(sys).setdefaultencoding('utf8')
>>> sys.stdout.write(a)
¦

但是,更好的解决方案可能是将sys.stdout 替换为包装器:

class StdOut(object):
    def write(self, string):
        if isinstance(string, unicode):
            string = string.encode(sys.__stdout__.encoding)
        sys.__stdout__.write(string)

>>> sys.stdout = StdOut()
>>> sys.stdout.write(a)
¦

【讨论】:

stdout 有许多不同的功能(关闭、刷新等)。这里最好只替换写函数

以上是关于python unicode处理print和sys.stdout.write之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

python 编码解码

python 处理异常 sys.exit出现错误,这是怎么回事?

python中sys.setdefaultencoding('utf-8')的作用

python中sys.setdefaultencoding('utf-8')的作用

Python第三天

Python标准库之Sys模块使用详解