每当我尝试使用
open(file_name, encoding='utf-8')
读取 UTF-8 编码的文本文件时,我总是收到错误消息,指出 ASCII 编解码器无法解码某些字符(例如,使用 for line in f: print(line)
时)
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getpreferredencoding()
'ANSI_X3.4-1968'
>>> import sys
>>> sys.getfilesystemencoding()
'ascii'
>>>
和
locale
命令打印:
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE=en_HK.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
我也有类似的问题。对我来说,最初没有设置环境变量
LANG
(您可以通过运行env
来检查)
$ python3 -c 'import locale; print(locale.getdefaultlocale())'
(None, None)
$ python3 -c 'import locale; print(locale.getpreferredencoding())'
ANSI_X3.4-1968
我可用的语言环境是(在新的 Ubuntu 18.04 Docker 映像上):
$ locale -a
C
C.UTF-8
POSIX
所以我选择了 utf-8 :
$ export LANG="C.UTF-8"
然后事情就开始了
$ python3 -c 'import locale; print(locale.getdefaultlocale())'
('en_US', 'UTF-8')
$ python3 -c 'import locale; print(locale.getpreferredencoding())'
UTF-8
如果您选择的区域设置不可用,例如
export LANG="en_US.UTF-8"
它不会工作:
$ python3 -c 'import locale; print(locale.getdefaultlocale())'
('en_US', 'UTF-8')
$ python3 -c 'import locale; print(locale.getpreferredencoding())'
ANSI_X3.4-1968
这就是为什么
locale
给出错误消息:
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
apt install locales-all
LC_ALL
、
LC_CTYPE
和
LANG
环境变量。从理论上讲,标准是好的,但根据我的经验,这些变量只会引起问题。它们有时会无缘无故地被设置为荒谬的值,例如非 UTF-8 字符集。然后,Python 在处理非 ASCII 文本时会抛出错误。
您可以通过找出这些环境变量的设置及其原因来解决此问题,并将它们更改为支持 Unicode 的内容。但系统配置可能会很麻烦。
Python 3.7 及更高版本提供了这两个快速修复:
运行此脚本时在环境中设置
print()
如果你做不到这一点,那么在脚本的早期,通过执行以下操作强制
PYTHONUTF8=1
stdout