当输送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"åäö"

有没有更好的方法让管道工作?


当前回答

我可以通过调用来“自动化”它:

def __fix_io_encoding(last_resort_default='UTF-8'):
  import sys
  if [x for x in (sys.stdin,sys.stdout,sys.stderr) if x.encoding is None] :
      import os
      defEnc = None
      if defEnc is None :
        try:
          import locale
          defEnc = locale.getpreferredencoding()
        except: pass
      if defEnc is None :
        try: defEnc = sys.getfilesystemencoding()
        except: pass
      if defEnc is None :
        try: defEnc = sys.stdin.encoding
        except: pass
      if defEnc is None :
        defEnc = last_resort_default
      os.environ['PYTHONIOENCODING'] = os.environ.get("PYTHONIOENCODING",defEnc)
      os.execvpe(sys.argv[0],sys.argv,os.environ)
__fix_io_encoding() ; del __fix_io_encoding

是的,如果这个“setenv”失败了,就有可能得到一个无限循环。

其他回答

您可能想尝试将环境变量“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
ö ☺ ☻

我可以通过调用来“自动化”它:

def __fix_io_encoding(last_resort_default='UTF-8'):
  import sys
  if [x for x in (sys.stdin,sys.stdout,sys.stderr) if x.encoding is None] :
      import os
      defEnc = None
      if defEnc is None :
        try:
          import locale
          defEnc = locale.getpreferredencoding()
        except: pass
      if defEnc is None :
        try: defEnc = sys.getfilesystemencoding()
        except: pass
      if defEnc is None :
        try: defEnc = sys.stdin.encoding
        except: pass
      if defEnc is None :
        defEnc = last_resort_default
      os.environ['PYTHONIOENCODING'] = os.environ.get("PYTHONIOENCODING",defEnc)
      os.execvpe(sys.argv[0],sys.argv,os.environ)
__fix_io_encoding() ; del __fix_io_encoding

是的,如果这个“setenv”失败了,就有可能得到一个无限循环。

在Windows上,当我从编辑器(如Sublime Text)运行Python代码时经常遇到这个问题,但如果从命令行运行就不会。

在这种情况下,检查编辑器的参数。在SublimeText的情况下,这个Python。Sublime-build解决了这个问题:

{
  "cmd": ["python", "-u", "$file"],
  "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
  "selector": "source.python",
  "encoding": "utf8",
  "env": {"PYTHONIOENCODING": "utf-8", "LANG": "en_US.UTF-8"}
}

上周我也遇到了类似的问题。在我的IDE (PyCharm)中很容易修复。

以下是我的解决方案:

从PyCharm菜单栏开始:File -> Settings…->编辑器->文件编码,然后设置:“IDE编码”,“项目编码”和“属性文件的默认编码”全部为UTF-8,她现在的工作就像一个魅力。

希望这能有所帮助!

克雷格·麦昆(Craig McQueen)的答案有争议的净化版。

import sys, codecs
class EncodedOut:
    def __init__(self, enc):
        self.enc = enc
        self.stdout = sys.stdout
    def __enter__(self):
        if sys.stdout.encoding is None:
            w = codecs.getwriter(self.enc)
            sys.stdout = w(sys.stdout)
    def __exit__(self, exc_ty, exc_val, tb):
        sys.stdout = self.stdout

用法:

with EncodedOut('utf-8'):
    print u'ÅÄÖåäö'