当输送Python程序的输出时,Python解释器会混淆编码并将其设置为None。这意味着这样一个程序:
# -*- coding: utf-8 -*-
print u"åäö"
正常运行时工作正常,但失败:
unicode编码错误:'ascii'编解码器无法编码字符u'\xa0'在位置0:序数不在范围(128)
在管道序列中使用时。
什么是最好的方法使这工作时管道?我能告诉它使用shell/文件系统/任何正在使用的编码吗?
到目前为止,我看到的建议是直接修改你的site.py,或者使用以下方法硬编码defaultencoding:
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print u"åäö"
有没有更好的方法让管道工作?
我在一个遗留应用程序中遇到了这个问题,并且很难确定在哪里打印了内容。我用这个方法帮助自己:
# encoding_utf8.py
import codecs
import builtins
def print_utf8(text, **kwargs):
print(str(text).encode('utf-8'), **kwargs)
def print_utf8(fn):
def print_fn(*args, **kwargs):
return fn(str(*args).encode('utf-8'), **kwargs)
return print_fn
builtins.print = print_utf8(print)
在我的脚本顶部,test.py:
import encoding_utf8
string = 'Axwell Λ Ingrosso'
print(string)
注意,这改变了所有调用打印使用编码,所以你的控制台将打印这个:
$ python test.py
b'Axwell \xce\x9b Ingrosso'
您可能想尝试将环境变量“PYTHONIOENCODING”更改为“utf_8”。我写了一页关于我在这个问题上的痛苦经历。
博客文章的Tl;dr:
import sys, locale, os
print(sys.stdout.encoding)
print(sys.stdout.isatty())
print(locale.getpreferredencoding())
print(sys.getfilesystemencoding())
print(os.environ["PYTHONIOENCODING"])
print(chr(246), chr(9786), chr(9787))
给你
utf_8
False
ANSI_X3.4-1968
ascii
utf_8
ö ☺ ☻
export PYTHONIOENCODING=utf-8
完成工作,但不能设置在python本身…
我们能做的是验证是否没有设置,并告诉用户在调用脚本之前设置它:
if __name__ == '__main__':
if (sys.stdout.encoding is None):
print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
exit(1)
更新以回复评论:
问题只存在于管道到标准输出时。
我在Fedora 25 Python 2.7.13中测试
python --version
Python 2.7.13
猫b.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
print sys.stdout.encoding
运行。/ b.py
UTF-8
运行。/b.p y| less
None
我在一个遗留应用程序中遇到了这个问题,并且很难确定在哪里打印了内容。我用这个方法帮助自己:
# encoding_utf8.py
import codecs
import builtins
def print_utf8(text, **kwargs):
print(str(text).encode('utf-8'), **kwargs)
def print_utf8(fn):
def print_fn(*args, **kwargs):
return fn(str(*args).encode('utf-8'), **kwargs)
return print_fn
builtins.print = print_utf8(print)
在我的脚本顶部,test.py:
import encoding_utf8
string = 'Axwell Λ Ingrosso'
print(string)
注意,这改变了所有调用打印使用编码,所以你的控制台将打印这个:
$ python test.py
b'Axwell \xce\x9b Ingrosso'