首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中打印unicode字符串,与环境无关

在python中打印unicode字符串,与环境无关
EN

Stack Overflow用户
提问于 2014-12-08 05:00:38
回答 4查看 5.7K关注 0票数 9

我正在尝试寻找一种通用的解决方案来从python脚本中打印unicode字符串。

要求是它必须在Python2.7和3.x中运行,在任何平台上,并且使用任何终端设置和环境变量(例如LANG=C或LANG=en_US.UTF-8)。

python打印函数在打印时会自动尝试对终端编码进行编码,但如果终端编码是ascii,则会失败。

例如,当环境为“LANG=enUS.UTF-8”时,可以执行以下操作:

代码语言:javascript
复制
x = u'\xea'
print(x)

但在Python2.7中,当“LANG=C”时失败:

代码语言:javascript
复制
UnicodeEncodeError: 'ascii' codec can't encode character u'\xea' in position 0: ordinal not in range(128)

无论LANG设置如何,以下命令都有效,但如果终端使用不同的unicode编码,则无法正确显示unicode字符:

代码语言:javascript
复制
print(x.encode('utf-8'))

期望的行为是,如果可能,总是在终端中显示unicode,如果终端不支持unicode,则显示一些编码。例如,如果终端仅支持ascii,则输出将采用UTF-8编码。基本上,目标是在python print函数工作时执行与python print函数相同的操作,但在print函数失败的情况下,使用一些默认编码。

EN

回答 4

Stack Overflow用户

发布于 2014-12-08 05:13:31

您可以通过告诉sys.stdout在其他情况下默认为LANG=C时使用UTF-8来处理ASCII码。

代码语言:javascript
复制
import sys, codecs

if sys.stdout.encoding is None or sys.stdout.encoding == 'ANSI_X3.4-1968':
    utf8_writer = codecs.getwriter('UTF-8')
    if sys.version_info.major < 3:
        sys.stdout = utf8_writer(sys.stdout, errors='replace')
    else:
        sys.stdout = utf8_writer(sys.stdout.buffer, errors='replace')

print(u'\N{snowman}')

上面的代码片段满足了您的需求:它可以在Python2.7和3.4中工作,并且当LANG处于非UTF-8设置(比如C )时,它不会中断。

它是not a new technique,但在文档中很难找到它。如上所述,它实际上遵循非UTF-8设置,比如ISO 8859-*。只有当Python错误地默认为ASCII时,它才会默认为UTF-8,从而中断应用程序。

票数 12
EN

Stack Overflow用户

发布于 2014-12-08 05:14:46

我不认为您应该尝试在Python级别上解决这个问题。记录您的应用程序需求,记录您运行的系统的区域设置,以便可以将其包含在错误报告中,并将其留在那里。

如果确实想这样做,至少要区分终端和管道;永远不要将数据输出到终端无法显式处理的终端;例如,不要输出UTF-8,因为在编码时,不可打印的codepoints > U+007F最终可能被解释为控制代码。

对于管道,默认输出UTF-8并使其可配置。

因此,您将检测是否正在使用TTY,然后基于此处理编码;对于终端,设置一个错误处理程序(选择replacebackslashreplace之一,为无法处理的任何字符提供替换字符或转义序列)。对于管道,请使用可配置的编解码器。

代码语言:javascript
复制
import codecs
import os
import sys

if os.isatty(sys.stdout.fileno()):
    output_encoding = sys.stdout.encoding
    errors = 'replace'
else:
    output_encoding = 'utf-8'  # allow override from settings
    errors = None  # perhaps parse from settings, not needed for UTF8
sys.stdout = codecs.getwriter(output_encoding)(sys.stdout, errors=errors)
票数 2
EN

Stack Overflow用户

发布于 2014-12-09 05:25:46

您可以自己使用特殊参数'backslashreplace'对字符串进行编码,以便将无法表示的字符转换为转义序列。在Python2中,您可以直接打印encode的结果,但是在Python3中,您需要首先将其decode回Unicode。

代码语言:javascript
复制
import sys
encoding = sys.stdout.encoding
print(s.encode(encoding, 'backslashreplace').decode(encoding))

如果sys.stdout.encoding不能提供您的终端所能处理的价值,那就是您必须处理的另一个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27347772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档