将unicode字符串打印到控制台确定但重定向到文件时失败。怎么修?

时间:2013-07-29 07:57:47

标签: python python-2.7 python-unicode

我在简体中文版的Windows XP上安装了Python 2.7.1,我有一个这样的程序(windows_prn_utf8.py):

#!/usr/bin/env python
# -*- coding: utf8 -*-

print unicode('\xE7\x94\xB5', 'utf8')

如果我在Windows CMD控制台上运行它,它输出正确的中文字符'电';但是,如果我尝试将命令输出重定向到文件。我收到了错误。

D:\Temp>windows_prn_utf8.py > 1.txt
Traceback (most recent call last):
  File "D:\Temp\windows_prn_utf8.py", line 4, in <module>
    print unicode('\xE7\x94\xB5', 'utf8')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u7535' in position 0: ordinal not in range(128)

我意识到这里缺少一个链接。在生成1.txt的情况下,应该有一种方法可以确定1.txt中的unicode字符是否应该用utf-8或codepage-936或其他编码进行编码。

那怎么解决呢?我的偏好是在1.txt中使用utf-8编码。谢谢。

enter image description here

4 个答案:

答案 0 :(得分:2)

似乎已经解决了,但我认为更多细节将有助于解释这个实际问题。

unicode('\xE7\x94\xB5', 'utf8')中的'utf8'告诉解释器如何解码你在另一个参数中提供的3个字节,以便在内部将字符表示为unicode对象:

In [6]: uobj = unicode('\xe7\x94\xb5','utf8')

In [7]: uobj
Out[7]: u'\u7535'

另一个例子是从utf-16表示创建相同的字符(这是默认显示的python并显示在上面的Out[7]行中):

In [8]: uobj = unicode('\x35\x75','utf16')

In [9]: uobj
Out[9]: u'\u7535'

在创建对象后的示例中,它成为print的参数,它尝试将其写入标准输出(控制台窗口,重定向到文件等)。复杂的是print必须在写入之前将该对象重新编码为字节流。在您的情况下,它看起来像默认使用的编码是ACSII,它不能代表该字符。

(如果控制台将尝试显示字符,它们将在窗口中重新解码并替换为相应的字体字形 - 这就是为什么您的输出和控制台都需要'说'相同的编码。)

从我看到的内容中,cmd.exe在字符编码时非常混乱,但我在其他操作系统上做的是在使用unicode对象encode打印/写入之前显式编码字节功能。这将返回存储在str对象中的编码字节序列:

In [10]: sobj = uobj.encode('utf8')

In [11]: type(sobj)
Out[11]: str

In [12]: sobj
Out[12]: '\xe7\x94\xb5'

In [13]: print sobj
电

现在print被赋予了str而不是unicode,它不需要对任何内容进行编码。在我的情况下,我的终端解码utf8,其字体包含该特定字符,因此它在我的屏幕上正确显示(希望现在在您的浏览器中)。

答案 1 :(得分:1)

设置PYTHONIOENCODING环境变量。

SET PYTHONIOENCODING=cp936
windows_prn_utf8.py > 1.txt

答案 2 :(得分:1)

在将其写入文件之前,您可以将其编码为utf-8。

f.write("电".encode("utf8"))

答案 3 :(得分:1)

使用codecs.open(文件名,编码)代替open(filename)并使用python写入文件。