Python3中locale.setlocale函数的异常行为问题咨询
我碰到一个奇怪的情况:两个开头代码完全一致的Python程序,表现却天差地别。初始代码是这样的:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from lxml import etree, html from lxml.builder import E import re import sys import locale #locale.setlocale(locale.LC_ALL, 'es_ES.UTF-8') locale.setlocale(locale.LC_ALL, '')
其中一个程序跑起来完全没问题,但另一个必须把第一行setlocale的注释去掉,同时把第二行空字符串的调用注释掉,才能避开这个报错:
Traceback (most recent call last):
File "./html2epub.py", line 11, in
locale.setlocale(locale.LC_ALL, '')
File "/usr/lib/python3.5/locale.py", line 594, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
更离谱的是,要是把LC_ALL设成空字符串以外的值,这个有问题的程序直接彻底跑不起来。
问题原因
为啥会这样?核心原因就是两个程序运行的系统环境locale配置不一样:
- 能正常跑的那个环境,系统已经正确配置了默认的UTF-8 locale(比如
es_ES.UTF-8已经生成并设为默认),Python调用locale.setlocale(locale.LC_ALL, '')时,能自动识别并应用系统默认的locale,自然不会报错。 - 报错的环境要么是默认locale没设成UTF-8,要么是
es_ES.UTF-8这个locale压根没在系统里生成,导致Python找不到可用的locale,直接抛出错误。
解决方案
针对报错的环境,有两种靠谱的处理方式:
1. 直接指定明确的locale(当前的临时解决方法)
修改代码,用明确的locale标识替换空字符串调用:
locale.setlocale(locale.LC_ALL, 'es_ES.UTF-8') #locale.setlocale(locale.LC_ALL, '')
⚠️ 注意:得先确保系统已经安装并生成了es_ES.UTF-8 locale。在Linux下可以用locale -a命令查看已有的locale列表,如果没找到,就用locale-gen es_ES.UTF-8命令生成它。
2. 配置系统默认locale为UTF-8(彻底解决)
在系统层面把默认locale设成UTF-8类型的,这样就能保留locale.setlocale(locale.LC_ALL, '')的调用,让Python自动适配:
- 编辑
/etc/locale.conf文件,添加或修改成以下内容:LC_ALL=es_ES.UTF-8 LANG=es_ES.UTF-8 - 运行
locale-gen es_ES.UTF-8生成对应的locale(如果还没生成) - 重启系统或者重新登录,让配置生效
内容的提问来源于stack exchange,提问作者Pedro A. Aranda

