Python / 编程 · 30 11 月, 2021 0

执行含有中文字符输出的Python脚本时报错:“UnicodeEncodeError: ‘ascii’ codec can’t encode characters…”该怎么办

注:以下内容适用于Python 3+。还在用2的同学不考虑升一下级么😅

发生了什么

众所周知,Python的字符管理就是一团浆糊。
当你在某些操作系统(比如最小安装的CentOS 7)的CLI界面执行涉及中文或者日文输出的Python脚本时,可能会遇到这样的错误提示:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

你可能会觉得很无辜:我不是在首行写了# -*- coding: utf-8 -*-吗?不是说好Python 3默认字符集就是UTF-8吗?……

自查一下

打开一个Python界面,执行:

import sys
print(sys.getdefaultencoding())
print(sys.stdout.encoding)
# 关于这两个命令的说明可参考以下链接:
# https://stackoverflow.com/questions/15530635/why-is-sys-getdefaultencoding-different-from-sys-stdout-encoding-and-how-does

看看两个print输出分别是啥?是不是一个输出“utf-8”,另一个输出“ANSI_X3.4-1968”或者别的什么玩意儿?

解决方案

参考了《How to set sys.stdout encoding in Python 3》 给出的方案,即在你的程序开头执行一句:

sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf8', buffering=1)
# 别忘了import sys

再跑脚本就不会报错且能输出正确的文字了。

彩蛋

可以试试执行sys.getfilesystemencoding()看输出的是不是“ascii”。引用网页 里给出的描述是这样的:

sys.getfilesystemencoding() should be the encoding that is used to encode OS data (filenames, command-line arguments, environment variables).

想要修改这个参数,爆栈网给出了惊人的方法:

sys.getfilesystemencoding = lambda: 'UTF-8'

👆你学废了吗?