在Ubuntu终端使用Python脚本显示UTF8字符串

1 投票
3 回答
4017 浏览
提问于 2025-04-16 23:24

在我的Python脚本中,我在Ubuntu的命令行上运行,它从MySQL数据库中选择UTF8编码的内容。

接下来,我想把这个字符串打印到控制台上。

但是显示出来的字符串有编码问题,带重音的字符没有正确显示。请问我该怎么解决这个问题呢?

最好是让脚本自己决定怎么处理,而不是设置系统环境,这样在其他系统上运行也会更简单。

3 个回答

1

文本的输入编码(这里是utf-8)其实并不重要。你应该尽快把utf8字节串转换成Unicode,然后再打印文本:

print(unicode_text)
  • 打印之前不要把文本编码成utf8
  • 不要修改sys.stdout来让它帮你用utf8编码文本

输出编码是由运行你脚本的环境决定的,这取决于地区设置(比如LANGLC_CTYPELC_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!!")

撰写回答