在Ubuntu终端使用Python脚本显示UTF8字符串
在我的Python脚本中,我在Ubuntu的命令行上运行,它从MySQL数据库中选择UTF8编码的内容。
接下来,我想把这个字符串打印到控制台上。
但是显示出来的字符串有编码问题,带重音的字符没有正确显示。请问我该怎么解决这个问题呢?
最好是让脚本自己决定怎么处理,而不是设置系统环境,这样在其他系统上运行也会更简单。
3 个回答
1
文本的输入编码(这里是utf-8)其实并不重要。你应该尽快把utf8字节串转换成Unicode,然后再打印文本:
print(unicode_text)
- 打印之前不要把文本编码成utf8
- 不要修改
sys.stdout
来让它帮你用utf8编码文本
输出编码是由运行你脚本的环境决定的,这取决于地区设置(比如LANG
、LC_CTYPE
、LC_ALL
)或者PYTHONIOENCODING
这个环境变量。不要无条件地输出utf8。
举个例子,如果地区设置没有配置好,你可以明确地指定它:
$ LANG=en_US.utf8 python your_script.py
确保你的终端能够显示相应的Unicode字符(需要安装合适的字体和地区设置(可以用locale -a
查看))。
换句话说,要修复输出问题,就要先修复环境,比如,将你的地区设置配置为默认使用C.UTF-8
。
1
你可以这样获取当前标准输出的编码方式:
>>> import sys
>>> sys.stdout.encoding
UTF-8
然后根据这个编码方式来处理你的Unicode字符串:
>>> u"Ä"
u'\xc4'
>>> sys.stdout.write(u"Ä".encode(enc, 'replace'))
使用'replace'可以避免出现Unicode编码错误,当某个字符在终端的编码中无法表示时,它会被替换成一个问号。
2
强烈建议你不要用“?”作为替代字符。只需将你的输出编码设置为UTF-8,这样就可以了。
for s in ("stdin","stdout","stderr"):
setattr(sys, s, io.TextIOWrapper(getattr(sys, s).detach(), encoding="utf8"))
另外,你可以把你的 PYTHONIOENCODING
环境变量设置为utf8,这样Python就不会再猜测输出编码了。
这两种方法都比手动编码要好得多,手动编码真的很傻。
如果你不想升级到Python3,我还建议你
from __future__ import unicode_literals
去掉那些让人烦的 u'...'
这种写法。
最近我开始用这样的方式来启动我的所有Python程序:
#!/usr/bin/env python3.2
# -*- coding: UTF-8 -*-
from __future__ import print_function
from __future__ import unicode_literals
import re
import sys
import os
if not (("PYTHONIOENCODING" in os.environ)
and
re.search("^utf-?8$", os.environ["PYTHONIOENCODING"], re.I)):
sys.stderr.write(sys.argv[0] + ": Please set your PYTHONIOENCODING envariable to utf8\n")
sys.exit(1)
import unicodedata
if unicodedata.unidata_version < "6.0.0":
print("WARNING: Your old UCD is out of date, expected at least 6.0.0 but got",
unicodedata.unidata_version)
wide_enough = (sys.maxunicode >= 0x10FFFF)
if not wide_enough:
print("WARNING: Narrow build detected, your Python lacks full Unicode support!!")