2012-08-07 67 views
4

蟒蛇编码错误

$ cat x.py 
x = u'Gen\xe8ve' 
print x 

一个简单的文件在运行时都会给我:

$ python x.py 
Genève 

然而,当作为“命令替换”运行将给:

$ echo $(python x.py) 
... 
UnicodeEncodeError: 'ascii' codec... 

我试过用不同的终端模拟器(xterm,gnome-term)和ttyS上的控制台。用bash和sh。用python2.4和2.7。 我已经尝试在运行python之前将LC_ALL或LANG设置为某些utf-8语言环境。 我检查了sys.getdefaultencoding()。 没有什么帮助。

从另一个进程(如java)调用脚本时也会出现问题,但上面是我发现复制它的最简单的方法。

我不明白这两个调用之间有什么区别。 任何人都可以帮忙吗?

+0

好的。我绝对可以重现这一点。 – 2012-08-07 11:30:38

回答

7

这里的问题是,在第二次调用中,您基本上正在写入只接受字节串​​(类文件对象)的管道。如果您尝试执行此同样的情况:

python x.py > my_file 
Traceback (most recent call last): 
File "x.py", line 2, in <module> 
    print x 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 3: ordinal not in range(128) 

由于接收器只能理解字节串,而不是Unicode字符,你必须先使用encode功能Unicode字符串编码成字节串:

x = u'Gen\xe8ve'.encode('utf-8') 
print x 

这将打印编码为utf-8字节串(字节序列)的unicode字符串,从而允许将其写入文件类对象。

$echo $(python x.py) 
Genève 
$python x.py 
Genève 
+1

很好的解释。 – 2012-08-07 11:35:28

+0

@Tichodroma谢谢 – 2012-08-07 11:36:05

+0

通常一个终端也只接受字节串​​(在Windows上它可能直接接受Unicode)。区别在于Python是否知道适当的字符编码或默认为ascii – jfs 2012-08-07 11:45:09

2

正如你怀疑的那样,当Python的标准输出不是已知的终端时,Python不知道如何打印unicode。考虑在打印之前对字符串进行编码:

# coding: utf-8 
x = u'Gen\xe8ve' 
print x.encode("utf-8") 

请注意,调用程序和您的脚本需要在通用编码中达成一致。