Python locale 多语言模块和我遇到的坑
Table of Contents
locale遇到的问题
今天工作上遇到一个 locale 相关的问题,关于字符串格式化的。不过让我们先从 locale 说起。
locale 简介
什么是locale
locale 这个单词中文翻译成地区或者地域,其实这个单词包含的意义要宽泛很多。locale 是根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统所定义的一个软件运行时的语言环境。通常情况下它可以按照涉及使用习惯分为12大类:
- 语言符号及其分类(LC_CTYPE)
- 数字(LC_NUMBERIC)
- 比较习惯(LC_COLLATE)
- 时间显示格式(LC_TIME)
- 货币单位(LC_MONETARY)
- 信息主要是提示信息,错误信息,状态信息,标题,标签,按钮和菜单等(LC_MESSAGES)
- 行么书写方式(LC_NAME)
- 地址书写方式(LC_ADDRESS)
- 电话号码书写方式(LC_TELEPHONE)
-度量衡表达方式(LC_MEASUREMENT)
- 默认纸张尺寸大小(LC_PAPER)
- 对locale 自身包含信息的概述(LC_IDENTIFICATION)
- 除此之外还有一个LANGUAGE参数,它与LC_MESSAGES相似
比如像下面的例子里:
在“简体中文”环境,运行date 命令,显示的是:
2016年11月24日 星期四 22时59分26秒 CST
而在英文环境下,运行date 命令,显示的是
Thu Nov 24 23:05:12 CST 2016
简单来说, locale 为计算机上提供了国际化和本地化转化的环境
locale 相关命令
在Unix下可以通过命令 locale 来查看当前语言环境,我的Mac上的显示如下:
➜ locale
LANG=
LC_COLLATE="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_ALL="zh_CN.UTF-8"
locale值格式类似为: 语言_地区.字符集
可以这样来查看系统支持locals值
locale -a
可以用如下的方式来临时改变shell的locale设定:
➜ test git:(master) ✗ LC_ALL=C
➜ test git:(master) ✗ export LC_ALL
➜ test git:(master) ✗ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL="C"
设置的时候注意以下几点:
- LANG,LC*的默认值,是最低级别的设置,如果LC*没有设置,则使用该值。类似于 LCALL
- LCALL,它是一个宏,如果该值设置了,则该值会覆盖所有LC*的设置值。注意,LANG的值不受该宏影响
- LCALL=C 意思是去除所有本地化的设置
Python locale
python提供了 locale 这个模块,可以用来操作locale相关数据,官方文档参见这里。
其中主要的结果方法如下
import locale
# 返回当前环境locale categorg相关的设定,category默认为 LC_CTYPE
# LC_CTYPE 决定字符处理函数相关行为,比如 string 函数
locale.getlocale([category])
# 尝试判断默认的locale设置,并且以元组的形式返回(language code, encoding)
locale.getdefaultlocale([envvars])
# 修改locale category 的设定为 locale的值, 比如locale.setlocale(locale.LC_ALL, 'C'), C 代表去除所有本地化设置
# 如果第二个参数locale没有提供,那么会返回category的设置
locale.setlocale(category[, locale])
# 很多程序会像下面这样开头,这样做会将所有的locale设置成用户默认的设置(通常是环境变量LANF的值)。
# 但setlocale() 不能在所有系统上保证线程安全性,这点要注意
import locale
locale.setlocale(locale.LC_ALL, '')
当在shell里启动python repl(交互器)时,默认的环境local设置为'C', 也就是没有本地化设置,这时候可以通过 locale.getdefaultlocale() 来查看shell当前环境的locale设置, 并通过 locale.setlocale(locale.LC_ALL, '') 将python解释器的locale设置成shell环境的locale,具体事例如下:
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale()
(None, None)
>>> locale.getdefaultlocale()
('zh_CN', 'UTF-8')
>>> locale.setlocale(locale.LC_ALL, '')
'zh_CN.UTF-8'
>>> locale.getdefaultlocale()
('zh_CN', 'UTF-8')
>>> locale.getlocale()
('zh_CN', 'UTF-8')
我踩的坑
strptime 和 strftime
正所谓当局者迷,今天当我遇到同样的代码,不同的环境(shell执行和pycharm执行)居然有不同的执行结果时,我百思不得其姐(嘿嘿)。
代码片段是关于 strptime 的:
import time
time.strptime('Thu, 24 Nov 2016 07:01:59 GMT', '%a, %d %b %Y %H:%M:%S GMT')
其实呢,strptime或者strftime格式化参数里有一些是跟locale相关的,比如这里的 %a %b 等,所以在不对的 locale 环境下,格式化出现了错误。
可以参考下面的示例:
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.strptime('Thu, 24 Nov 2016 07:01:59 GMT', '%a, %d %b %Y %H:%M:%S GMT')
time.struct_time(tm_year=2016, tm_mon=11, tm_mday=24, tm_hour=7, tm_min=1, tm_sec=59, tm_wday=3, tm_yday=329, tm_isdst=-1)
>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
'zh_CN.UTF-8'
>>> time.strptime('Thu, 24 Nov 2016 07:01:59 GMT', '%a, %d %b %Y %H:%M:%S GMT')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 467, in _strptime_time
return _strptime(data_string, format)[0]
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Thu, 24 Nov 2016 07:01:59 GMT' does not match format '%a, %d %b %Y %H:%M:%S GMT'
>>> time.strptime('2016 07:01:59', '%Y %H:%M:%S')
time.struct_time(tm_year=2016, tm_mon=1, tm_mday=1, tm_hour=7, tm_min=1, tm_sec=59, tm_wday=4, tm_yday=1, tm_isdst=-1)
>>>
阿里云oss sdk 使用遇到的问题
用阿里云oss-python-SDK上传文件时,当我本地locale设置成 zh_CN.UTF-8 时,就回一直出问题,原因就在于上述的 strptime, 阿里云sdk代码片段如下:
def to_unixtime(time_string, format_string):
with _STRPTIME_LOCK:
return int(calendar.timegm(time.strptime(time_string, format_string)))
然而从oss服务器上获得的timestring是这样的: Thu, 24 Nov 2016 07:01:59 GMT, 所以在我的环境里做格式化就会出错,所以我对代码做了如下修改:
def to_unixtime(time_string, format_string):
with _STRPTIME_LOCK:
time_locale = locale.setlocale(locale.LC_TIME)
if time_locale.find('en') != 0 and time_locale != 'C':
locale.setlocale(locale.LC_TIME, 'en_US')
unixtime = int(calendar.timegm(time.strptime(time_string, format_string)))
locale.setlocale(locale.LC_TIME, time_locale)
else:
unixtime = int(calendar.timegm(time.strptime(time_string, format_string)))
return unixtime
在调用 strptime 这个方法前增加了兼容,先检查locale,如果不是英文类型并且不是默认的"C"类型时,将 LC_TIME 切换成英文,执行完 strptime 后再还原回来。
参考资料
- https://docs.python.org/2/library/locale.html#module-locale
- http://blog.csdn.net/Nicolase/article/details/42499521
- http://www.cnblogs.com/dolphi/p/3622570.html
- https://docs.python.org/2/library/time.html#time.strptime
Python locale 多语言模块和我遇到的坑的更多相关文章
- SpaceVim 语言模块 python
原文连接: https://spacevim.org/cn/layers/lang/python/ 模块简介 功能特性 依赖安装及启用模块 启用模块 语法检查 代码格式化 格式化 imports 快捷 ...
- Python学习笔记-常用模块
1.python模块 如果你退出 Python 解释器并重新进入,你做的任何定义(变量和方法)都会丢失.因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作 ...
- Day5 - Python基础5 常用模块学习
Python 之路 Day5 - 常用模块学习 本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shel ...
- python 学习day5(模块)
一.模块介绍 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能 ...
- Python基础5-常用模块
本节大纲 模块介绍 time &datetime模块 random os sys shutil shelve xml处理 yaml处理 configparser hashlib subproc ...
- python学习笔记_week5_模块
模块 一.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能), 本质就是.py结尾的python文件(文件名:test.py,对应模块名:test) 包:用来从逻辑上 ...
- Python基础5 常用模块学习
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...
- Python正则表达式与re模块介绍
Python中通过re模块实现了正则表达式的功能.re模块提供了一些根据正则表达式进行查找.替换.分隔字符串的函数.本文主要介绍正则表达式先关内容以及re模块中常用的函数和函数常用场景. 正则表达式基 ...
- Python(五)模块
本章内容: 模块介绍 time & datetime random os sys json & picle hashlib XML requests ConfigParser logg ...
随机推荐
- jquery-validate插件
jQuery Validation 插件 优点:1.表单验证非常简单方便,并且提供了许多配置项目2.国际化,可以自定义提示信息 命令行安装 //初始化bowerbower init //使用bower ...
- Android基础Activity篇——Intent返回数据给上一个活动
1.如果活动B要将数据返回给活动A,那么需要以下三步: 1.1在活动A中使用startActivityForResult()方法启动活动B. 1.2在活动B中使用setResult()方法传回Iten ...
- Python 爬虫实战(二):使用 requests-html
Python 爬虫实战(一):使用 requests 和 BeautifulSoup,我们使用了 requests 做网络请求,拿到网页数据再用 BeautifulSoup 解析,就在前不久,requ ...
- 【Node.js】一个愚蠢的Try Catch过错
前段时间学习<深入浅出Nodejs>时,在第四章 - 异步编程中作者朴灵曾提到,异步编程的难点之一是异常处理,书中描述"尝试对异步方法进行try/catch操作只能捕获当次事件循 ...
- js有限状态机
http://www.ruanyifeng.com/blog/2013/09/finite-state_machine_for_javascript.html 有限状态机(Finite-state m ...
- Eclipse:很不错的插件-devStyle,将你的eclipse变成idea风格
使用教程 https://blog.csdn.net/stillonmyway/article/details/79109741 我使用使用的是护眼型的
- 同步软件UltraCompare 64位 软件及注册机
软件及注册机下载: https://share.weiyun.com/f09e6243887e374ead1b3a3ab8f611a9 软件官方下载地址: https://www.ultraedit ...
- 如何使用Win32API绘制树
一.这个已经有几年时间了,刚开始学习charlie的<windows程序设计>的时候做的.现在看来,代码很乱,虽然后来还整理过几次,现在这方面没什么兴趣了,有兴趣的可自由下载. 二.绘制二 ...
- java运行顺序-JVM之九
简化顺序版本是: 父类的静态成员赋值和静态块,代码排版先后顺序执行,只运行一次 子类的静态成员赋值和静态块,代码排版先后顺序执行,只运行一次 父类代码块 父类构造方法 子类初始化块 子类构造方法 再次 ...
- 找子串替换(kmp)poj1572
题目链接:http://poj.org/problem?id=1572 输入数据时要注意,这里是string型 用getline(cin,origin[i]); #include <string ...