当管道Python程序的输出,Python解释无法了解编码,并将其设置为无。这意味着节目是这样的:

# -*- coding: utf-8 -*-
print u"åäö"

将正常运行时工作得很好,但失败:

  

UnicodeEncodeError: 'ASCII' 编解码器不能编码字符U位置0 '\ XA0':序数不在范围内(128)

在一个管顺序使用时。

什么是管道时,使这项工作的最佳方式是什么?我可以告诉它使用任何编码壳/文件系统/无论是使用?

迄今我所看到的建议是直接修改您的site.py,或使用本hack硬编码defaultencoding:

# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print u"åäö"

有没有更好的办法,使管道的工作?

有帮助吗?

解决方案

在脚本中运行时,因为Python的编码输出到任何编码您的终端应用程序正在使用你的代码工作。如果您管道必须自己编码。

经验法则是:始终使用Unicode内部。解码收到的东西,你编码送什么。

# -*- coding: utf-8 -*-
print u"åäö".encode('utf-8')

另一个说教例子是Python程序为ISO-8859-1和UTF-8之间进行转换,使一切大写在两者之间。

import sys
for line in sys.stdin:
    # Decode what you receive:
    line = line.decode('iso8859-1')

    # Work with Unicode internally:
    line = line.upper()

    # Encode what you send:
    line = line.encode('utf-8')
    sys.stdout.write(line)

设置系统默认的编码是一个坏主意,因为一些使用模块和库可以依靠的事实,这是ASCII。不这样做。

其他提示

首先,关于此解决方案:

# -*- coding: utf-8 -*-
print u"åäö".encode('utf-8')

这是不实际的,明确将其定编码每次打印。这将是重复的和容易出错的。

一个更好的解决方案是改变的 sys.stdout 是在程序的开始时,与所选择的编码来进行编码。这里是一个解决方案,我在 Python的发现:如何为SYS .stdout.encoding通过选择,特别是评论 “TOKA”:

import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

您可能想尝试改变环境变量“PYTHONIOENCODING”到“UTF_8”。我已在考验这个问题写了一个页面

铊;博客帖子的DR:

给你

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)

更新回复注释: 问题管道到stdout时只是存在。 我在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.py |少

None

我有一个类似的问题,上周。这是很容易在我的IDE(PyCharm)来固定。

下面是我的解决办法:

从PyCharm菜单栏开始:文件 - >设置 - >编辑 - >文件编码,然后设置:“IDE编码”,“项目编码”和“默认编码属性文件”一切以UTF-8和她现在就像一个魅力。

希望这有助于!

这是值得商榷的消毒版本克雷格·麦奎因的回答。

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'ÅÄÖåäö'

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

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”失败。

我想我要在这里提到的东西,我不得不花了很长的时间与之前我终于意识到发生了什么实验。这可能是非常明显这里给大家,他们没有打扰提到它。但它会一直帮助我,如果他们有,所以这一原则...!

NB:我使用的Jython 具体地说,V 2.7,所以只可能这可能不适到 CPython的 ...

NB2:这里我.py文件的前两行是:

# -*- coding: utf-8 -*-
from __future__ import print_function

在“%”(又名“插值算”)串建设机制造成额外的问题太...如果“环境”的默认编码是ASCII,并尝试做一些像

print( "bonjour, %s" % "fréd" )  # Call this "print A"

您将在Eclipse中运行没有困难......在Windows命令行(DOS窗口),你会发现,编码的代码页850个(我的Windows 7操作系统)或类似的东西,它至少可以处理欧洲重音字符,所以它会工作。

print( u"bonjour, %s" % "fréd" ) # Call this "print B"

也将起作用。

如果,OTOH,你直接从CLI文件,标准输出编码将是无,这将默认为ASCII(我的OS反正),这将无法处理任何一种上述印刷品... (害怕编码误差)。

,那么你可能会认为通过使用重定向您的标准输出

sys.stdout = codecs.getwriter('utf8')(sys.stdout)

和尝试在CLI管道运行到一个文件中。很奇怪的是,打印上面会工作......但打印上述B将抛出的编码错误!下面将然而工作确定:

print( u"bonjour, " + "fréd" ) # Call this "print C"

我来(临时)的结论是,如果被指定的字符串是一个的Unicode 使用字符串的“U”前缀被提交到它似乎涉及使用默认的环境编码,<百分比 - 处理机制STRONG>不管你是否已设定标准输出重定向!

人们如何应对,这是选择的问题。我会欢迎一个Unicode专家说,为什么出现这种情况,我是否弄错了以某种方式,什么这个首选的解决方案,它是否也适用于的 CPython的,无论它发生在Python 3等等。

在Ubuntu的12.10和GNOME终端,当该程序被打印到标准输出产生没有错误或钩挂到其他程序的配管。两个文件编码和终端编码是 UTF-8

$ cat a.py
# -*- coding: utf-8 -*-
print "åäö"
$ python a.py
åäö
$ python a.py | tee out
åäö

什么操作系统和终端仿真器是您使用?我听到一些同事也有类似的问题,当使用的iTerm 2 和OS X;的iTerm 2可能是罪魁祸首。

更新:这个答案是错的 - 详见注释

我跑进一个遗留应用这个问题,并且它是难以识别被打印在那里什么。我顺手拿了这个黑客:

# 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'
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top