在Python中管道stdout时设置正确的编码

2024-03-29 06:51:47 发布

您现在位置:Python中文网/ 问答频道 /正文

当通过管道传输Python程序的输出时,Python解释器会对编码感到困惑,并将其设置为None。这意味着这样一个程序:

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

正常运行时可以正常工作,但失败的原因是:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128)

在管道序列中使用时。

在配管的时候,什么是最好的方法?我能告诉它使用shell/文件系统/正在使用的任何编码吗?

到目前为止,我看到的建议是直接修改site.py,或者使用以下方法对defaultencoding进行硬编码:

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

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


Tags: 方法in程序none编码管道sysascii
3条回答

首先,关于这个解决方案:

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

每次都用给定的编码显式打印是不实际的。这将是重复和容易出错的。

更好的解决方案是在程序开始时更改sys.stdout,使用选定的编码进行编码。以下是我在Python: How is sys.stdout.encoding chosen?上找到的一个解决方案,特别是“toka”的一个注释:

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

您可能想尝试将环境变量“pythonionecoding”更改为“utf_8”。我写了一篇page on my ordeal with this problem

博客作者:

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
ö ☺ ☻

在脚本中运行时,代码可以工作,因为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。别这么做。

相关问题 更多 >