cla*_*800 8 python unicode encoding utf-8
我正在尝试找到一个通用的解决方案来从python脚本中打印unicode字符串.
要求是它必须在任何平台上的python 2.7和3.x以及任何终端设置和环境变量(例如LANG = C或LANG = en_US.UTF-8)中运行.
python打印功能在打印时自动尝试编码为终端编码,但如果终端编码为ascii则失败.
例如,以下在环境"LANG = enUS.UTF-8"时有效:
x = u'\xea'
print(x)
Run Code Online (Sandbox Code Playgroud)
但是当"LANG = C"时,它在python 2.7中失败了:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xea' in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
以下工作无论LANG设置如何,但如果终端使用不同的unicode编码,则无法正确显示unicode字符:
print(x.encode('utf-8'))
Run Code Online (Sandbox Code Playgroud)
如果可能的话,期望的行为是始终在终端中显示unicode,如果终端不支持unicode,则显示一些编码.例如,如果终端仅支持ascii,则输出将为UTF-8编码.基本上,目标是在python打印功能工作时做同样的事情,但是在打印功能失败的情况下,使用一些默认编码.
use*_*342 11
您可以LANG=C通过告知sys.stdout默认为UTF-8的情况来处理这种情况,否则它将默认为ASCII.
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}')
Run Code Online (Sandbox Code Playgroud)
上面的代码片段符合您的要求:它适用于Python 2.7和3.4,并且LANG在非UTF-8设置中不会中断,例如C.
它不是一种新技术,但在文档中很难找到.如上所述,它实际上尊重非UTF-8设置,例如ISO 8859-*.如果Python伪装成ASCII,打破应用程序,它只默认为UTF-8.
Amb*_*ber -1
您可以处理异常:
def always_print(s):
try:
print(s)
except UnicodeEncodeError:
print(s.encode('utf-8'))
Run Code Online (Sandbox Code Playgroud)