检查事项
这是我发现的,按照我推荐的检查方式排列:
- 环境变量
LC_ALL、LANG、LC_CTYPE、LANGUAGE
- Python特有的环境变量
PYTHONIOENCODING,PYTHONCOERCECLOCALE
(其影响可能受程序参数-E影响;可以查看sys.flags.ignore_environment)
- Windows 特定的控制台编码
PYTHONLEGACYWINDOWSSTDIO
- Python
sys 模块
- 函数
sys.getdefaultencoding()(推论函数sys.setdefaultencoding已从Python 3中移除)
sys.stdin.encoding
sys.stdout.encoding
sys.stderr.encoding
- 文件系统编码设置
sys.getfilesystemencoding()
- Python 文件头
-*- coding: utf-8 -*-
-
locale模块
- 函数调用
locale.nl_langinfo(locale.CODESET)(似乎不适用于 Windows Python 3.7,适用于 Debian Python 3.5)
- 函数
locale.getdefaultlocale
- 函数
locale.getpreferredencoding(在某些系统上工作方式不同)
-
gettext 模块和各种设施(我不会全部列出)
- 传递给
gettext.install(application, directory) 或gettext.bindtextdomain(domain, directory) 等函数的目录内容
打印值
这里是列出其中大部分值的快速脚本:
import os, sys, locale
print('environment:')
print('-E (ignore PYTHON* environment variables) ? %s' %
(True if sys.flags.ignore_environment else False))
for env in ('LC_ALL', 'LANG', 'LC_CTYPE',
'LANGUAGE', 'PYTHONIOENCODING',
'PYTHONLEGACYWINDOWSSTDIO'):
if env in os.environ:
print('"%s"="%s"' % (env, os.environ[env]))
else:
print('"%s" not set' % env)
print()
print('sys module:')
print('getdefaultencoding "%s"' % sys.getdefaultencoding())
print('sys.stdin.encoding "%s"' % sys.stdin.encoding)
print('sys.stdout.encoding "%s"' % sys.stdout.encoding)
print('sys.stderr.encoding "%s"' % sys.stderr.encoding)
print()
print('locale:')
try:
getattr(locale,'nl_langinfo')
print('locale.nl_langinfo(locale.CODESET) "%s"' \
% locale.nl_langinfo(locale.CODESET))
except AttributeError:
print('locale.nl_langinfo not available')
print('locale.getdefaultlocale()[1] "%s"' \
% locale.getdefaultlocale()[1])
print('locale.getpreferredencoding() "%s"' \
% locale.getpreferredencoding())
三个系统上的打印值
- Windows 10 3.7
- Debian 9 和 3.5
- Ubuntu 14 和 3.4
在使用 Python 3.7 的 Windows 10 上,会打印出来
environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set
"LANG" not set
"LC_CTYPE" not set
"LANGUAGE" not set
"PYTHONIOENCODING"="UTF-8"
"PYTHONLEGACYWINDOWSSTDIO" not set
sys module:
getdefaultencoding "utf-8"
sys.stdin.encoding "UTF-8"
sys.stdout.encoding "UTF-8"
sys.stderr.encoding "UTF-8"
locale:
locale.nl_langinfo not available
locale.getdefaultlocale()[1] "cp1252"
locale.ngetpreferredencoding() "cp1252"
在使用 Python 3.5 的 Debian 9 上,会打印出来
environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set
"LANG"="en_GB.UTF-8"
"LC_CTYPE" not set
"LANGUAGE" not set
"PYTHONIOENCODING" not set
"PYTHONLEGACYWINDOWSSTDIO" not set
sys module:
getdefaultencoding "utf-8"
sys.stdin.encoding "UTF-8"
sys.stdout.encoding "UTF-8"
sys.stderr.encoding "UTF-8"
locale:
locale.nl_langinfo(locale.CODESET) "UTF-8"
locale.getdefaultlocale()[1] "UTF-8"
locale.ngetpreferredencoding() "UTF-8"
在使用 Python 3.4 的 Ubuntu 14.04 上,会打印出来
environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set
"LANG"="en_US.UTF-8"
"LC_CTYPE" not set
"LANGUAGE"="en_US:"
"PYTHONIOENCODING" not set
"PYTHONLEGACYWINDOWSSTDIO" not set
sys module:
getdefaultencoding "utf-8"
sys.stdin.encoding "UTF-8"
sys.stdout.encoding "UTF-8"
sys.stderr.encoding "UTF-8"
locale:
locale.nl_langinfo(locale.CODESET) "UTF-8"
locale.getdefaultlocale()[1] "UTF-8"
locale.getpreferredencoding() "UTF-8"
不幸的是,当我遇到安装模块的 unicode 打印问题时,并不能立即看出哪个设置会影响该模块。更令人困惑的是,了解这些不同的可能参数和设置如何相互作用更加令人困惑。有许多设置组合需要测试。
但这一点可能会帮助某人入门。
另请参阅 SO Question How to set sys.stdout encoding in Python 3? 的有用答案。
需要审查的相关 PEP
来自this pymotw article、python how-to unicode、python sys module、python locale module 的一些帮助。