23.2. locale — 国际化服务 — Python 文档
23.2. 语言环境 — 国际化服务
locale 模块打开对 POSIX 语言环境数据库和功能的访问。 POSIX 语言环境机制允许程序员处理应用程序中的某些文化问题,而无需程序员了解执行软件的每个国家/地区的所有细节。
locale 模块是在 _locale
模块之上实现的,如果可用,该模块又使用 ANSI C 语言环境实现。
locale 模块定义了以下异常和函数:
- exception locale.Error
- 无法识别传递给 setlocale() 的语言环境时引发的异常。
- locale.setlocale(category, locale=None)
如果给出 locale 而不是
None
,setlocale() 修改 category 的区域设置。 可用类别列在下面的数据描述中。 locale 可以是一个字符串,也可以是两个字符串(语言代码和编码)的迭代。 如果它是可迭代的,则使用语言环境别名引擎将其转换为语言环境名称。 空字符串指定用户的默认设置。 如果区域设置的修改失败,则会引发异常 Error。 如果成功,则返回新的语言环境设置。如果省略 locale 或
None
,则返回 category 的当前设置。setlocale() 在大多数系统上不是线程安全的。 应用程序通常以调用
import locale locale.setlocale(locale.LC_ALL, '')
这会将所有类别的语言环境设置为用户的默认设置(通常在
LANG
环境变量中指定)。 如果此后未更改语言环境,则使用多线程应该不会引起问题。
- locale.localeconv()
将本地约定的数据库作为字典返回。 该字典具有以下字符串作为键:
类别
钥匙
意义
'decimal_point'
小数点字符。
'grouping'
指定
'thousands_sep'
预期的相对位置的数字序列。 如果序列以 CHAR_MAX 结束,则不会执行进一步的分组。 如果序列以0
结束,则重复使用最后一个组大小。'thousands_sep'
组之间使用的字符。
'int_curr_symbol'
国际货币符号。
'currency_symbol'
当地货币符号。
'p_cs_precedes/n_cs_precedes'
货币符号是否在值之前(对于正数) 负值)。
'p_sep_by_space/n_sep_by_space'
货币符号是否通过空格与值分隔(对于正数,分别为: 负值)。
'mon_decimal_point'
用于货币价值的小数点。
'frac_digits'
在货币值的本地格式中使用的小数位数。
'int_frac_digits'
货币值的国际格式中使用的小数位数。
'mon_thousands_sep'
用于货币值的组分隔符。
'mon_grouping'
相当于
'grouping'
,用于货币价值。'positive_sign'
用于注释正货币值的符号。
'negative_sign'
用于注释负货币价值的符号。
'p_sign_posn/n_sign_posn'
符号的位置(对于正响应。 负值),见下文。
所有数值都可以设置为 CHAR_MAX 以指示在此语言环境中没有指定值。
'p_sign_posn'
和'n_sign_posn'
的可能值如下所示。价值
解释
0
货币和价值用括号括起来。
1
该符号应位于价值和货币符号之前。
2
该标志应遵循价值和货币符号。
3
符号应紧跟在值之前。
4
符号应紧跟在值之后。
CHAR_MAX
此语言环境中未指定任何内容。
如果区域设置不同且数字或货币字符串是非 ASCII,该函数将
LC_CTYPE
区域设置临时设置为LC_NUMERIC
区域设置或LC_MONETARY
区域设置。 此临时更改会影响其他线程。在 3.6.5 版更改: 该功能现在在某些情况下将
LC_CTYPE
语言环境临时设置为LC_NUMERIC
语言环境。
- locale.nl_langinfo(option)
以字符串形式返回一些特定于语言环境的信息。 此功能并非在所有系统上都可用,并且可能的选项集也可能因平台而异。 可能的参数值是数字,在 locale 模块中提供了符号常量。
nl_langinfo() 函数接受以下键之一。 大多数描述取自 GNU C 库中的相应描述。
- locale.CODESET
获取一个字符串,其中包含所选语言环境中使用的字符编码的名称。
- locale.D_T_FMT
获取一个字符串,该字符串可用作 time.strftime() 的格式字符串,以特定于语言环境的方式表示日期和时间。
- locale.D_FMT
获取一个字符串,该字符串可用作 time.strftime() 的格式字符串,以特定于语言环境的方式表示日期。
- locale.T_FMT
获取一个字符串,该字符串可用作 time.strftime() 的格式字符串,以特定于语言环境的方式表示时间。
- locale.T_FMT_AMPM
获取 time.strftime() 的格式字符串,以 am/pm 格式表示时间。
- DAY_1 ... DAY_7
获取一周中第 n 天的名称。
笔记
这遵循美国惯例
DAY_1
是星期日,而不是国际惯例 (ISO 8601) 星期一是一周的第一天。
- ABDAY_1 ... ABDAY_7
获取一周中第 n 天的缩写名称。
- MON_1 ... MON_12
获取第 n 个月的名称。
- ABMON_1 ... ABMON_12
获取第 n 个月的缩写名称。
- locale.RADIXCHAR
获取基数字符(十进制点、十进制逗号等)。
- locale.THOUSEP
获取千位的分隔符(三位数为一组)。
- locale.YESEXPR
获取可与 regex 函数一起使用的正则表达式,以识别对是/否问题的肯定响应。
笔记
该表达式的语法适用于 C 库中的
regex()
函数,这可能与 re 中使用的语法不同。
- locale.NOEXPR
获取可与 regex(3) 函数一起使用的正则表达式,以识别对是/否问题的否定响应。
- locale.CRNCYSTR
获取货币符号,如果符号应出现在值之前,则以“-”开头,如果符号应出现在值之后,则以“+”开头,或者以“.”开头。 如果符号应该替换基数字符。
- locale.ERA
获取代表当前语言环境中使用的时代的字符串。
大多数语言环境没有定义这个值。 定义此值的语言环境的一个例子是日语。 在日本,日期的传统表示包括与当时天皇统治时期相对应的时代名称。
通常不需要直接使用这个值。 在格式字符串中指定
E
修饰符会导致 time.strftime() 函数使用此信息。 未指定返回字符串的格式,因此您不应假设在不同系统上都知道它。
- locale.ERA_D_T_FMT
获取 time.strftime() 的格式字符串,以特定于区域设置的基于时代的方式表示日期和时间。
- locale.ERA_D_FMT
获取 time.strftime() 的格式字符串,以特定于语言环境的基于时代的方式表示日期。
- locale.ERA_T_FMT
获取 time.strftime() 的格式字符串,以特定于区域设置的基于时代的方式表示时间。
- locale.ALT_DIGITS
获取最多 100 个值的表示,用于表示值 0 到 99。
- locale.getdefaultlocale([envvars])
尝试确定默认区域设置并将它们作为
(language code, encoding)
形式的元组返回。根据 POSIX,未调用
setlocale(LC_ALL, )
的程序使用便携式'C'
语言环境运行。 调用setlocale(LC_ALL,
)
让它使用由LANG
变量定义的默认语言环境。 由于我们不想干扰当前的语言环境设置,因此我们以上述方式模拟行为。为了保持与其他平台的兼容性,不仅测试了
LANG
变量,还测试了作为 envvars 参数给出的变量列表。 将使用第一个找到的定义。 envvars 默认为 GNU gettext 中使用的搜索路径; 它必须始终包含变量名'LANG'
。 GNU gettext 搜索路径依次包含'LC_ALL'
、'LC_CTYPE'
、'LANG'
和'LANGUAGE'
。除代码
'C'
外,语言代码对应RFC 1766。 语言代码和编码如果它们的值无法确定,可能是None
。
- locale.getlocale(category=LC_CTYPE)
以包含 语言代码 、 编码 的序列形式返回给定语言环境类别的当前设置。 category 可以是
LC_*
值之一,除了 LC_ALL。 默认为 LC_CTYPE。除代码
'C'
外,语言代码对应RFC 1766。 语言代码和编码如果它们的值无法确定,可能是None
。
- locale.getpreferredencoding(do_setlocale=True)
根据用户偏好返回用于文本数据的编码。 用户偏好在不同系统上的表达方式不同,并且在某些系统上可能无法以编程方式使用,因此此函数仅返回猜测值。
在某些系统上,需要调用 setlocale() 来获取用户首选项,因此该函数不是线程安全的。 如果不需要或不需要调用 setlocale,则 do_setlocale 应设置为
False
。
- locale.normalize(localename)
返回给定语言环境名称的规范化语言环境代码。 返回的区域设置代码被格式化以用于 setlocale()。 如果规范化失败,则原名原样返回。
如果给定的编码未知,则该函数默认为区域设置代码的默认编码,就像 setlocale()。
- locale.resetlocale(category=LC_ALL)
将 category 的语言环境设置为默认设置。
默认设置通过调用 getdefaultlocale() 确定。 category 默认为 LC_ALL。
- locale.strcoll(string1, string2)
- 根据当前的 LC_COLLATE 设置比较两个字符串。 与任何其他比较函数一样,返回负值或正值或
0
,具体取决于 string1 是在 string2 之前或之后整理还是等于它。
- locale.strxfrm(string)
- 将字符串转换为可用于识别区域设置的比较的字符串。 例如,
strxfrm(s1) < strxfrm(s2)
等价于strcoll(s1, s2) < 0
。 当重复比较相同的字符串时可以使用此函数,例如 在整理字符串序列时。
- locale.format(format, val, grouping=False, monetary=False)
根据当前的 LC_NUMERIC 设置格式化数字 val。 格式遵循
%
运算符的约定。 对于浮点值,如果合适,小数点会被修改。 如果 grouping 为真,也考虑分组。如果 monetary 为真,则转换使用货币千位分隔符和分组字符串。
请注意,此功能仅适用于一个 %char 说明符。 对于整个格式字符串,请使用 format_string()。
- locale.format_string(format, val, grouping=False)
- 像在
format % val
中那样处理格式说明符,但会考虑当前的语言环境设置。
- locale.currency(val, symbol=True, grouping=False, international=False)
根据当前的 LC_MONETARY 设置格式化数字 val。
如果 symbol 为 true(这是默认值),则返回的字符串包含货币符号。 如果 grouping 为 true(这不是默认值),则使用该值进行分组。 如果 international 为真(这不是默认值),则使用国际货币符号。
请注意,此函数不适用于“C”语言环境,因此您必须首先通过 setlocale() 设置语言环境。
- locale.str(float)
- 使用与内置函数
str(float)
相同的格式格式化浮点数,但考虑小数点。
- locale.delocalize(string)
根据 LC_NUMERIC 设置,将字符串转换为规范化数字字符串。
3.5 版中的新功能。
- locale.atof(string)
- 按照 LC_NUMERIC 设置将字符串转换为浮点数。
- locale.atoi(string)
- 将字符串转换为整数,遵循 LC_NUMERIC 约定。
- locale.LC_CTYPE
- 字符类型函数的语言环境类别。 根据该类别的设置,处理大小写的模块 string 的功能会改变它们的行为。
- locale.LC_TIME
- 时间格式的语言环境类别。 函数 time.strftime() 遵循这些约定。
- locale.LC_MONETARY
- 用于格式化货币值的区域设置类别。 可用选项可从 localeconv() 函数获得。
- locale.LC_MESSAGES
- 消息显示的语言环境类别。 Python 当前不支持特定于应用程序的区域设置感知消息。 操作系统显示的消息,如 os.strerror() 返回的消息,可能会受此类别的影响。
- locale.LC_NUMERIC
- 用于格式化数字的区域设置类别。 locale 的函数 format()、atoi()[X43X]、atof() 和 str()模块受该类别的影响。 所有其他数字格式操作不受影响。
- locale.LC_ALL
- 所有区域设置的组合。 如果在更改区域设置时使用此标志,则会尝试为所有类别设置区域设置。 如果任何类别都失败了,则根本不会更改任何类别。 使用此标志检索区域设置时,将返回一个字符串,指示所有类别的设置。 此字符串稍后可用于恢复设置。
- locale.CHAR_MAX
- 这是一个符号常量,用于 localeconv() 返回的不同值。
例子:
>>> import locale
>>> loc = locale.getlocale() # get current locale
# use German locale; name might vary with platform
>>> locale.setlocale(locale.LC_ALL, 'de_DE')
>>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut
>>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
>>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
>>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale
23.2.1. 背景、细节、提示、技巧和注意事项
C 标准将语言环境定义为程序范围的属性,更改可能相对昂贵。 最重要的是,某些实现以这样的方式被破坏,频繁的区域设置更改可能会导致核心转储。 这使得正确使用语言环境有些痛苦。
最初,当程序启动时,语言环境是 C
语言环境,无论用户的首选语言环境是什么。 有一个例外:LC_CTYPE 类别在启动时更改,以将当前语言环境编码设置为用户首选的语言环境编码。 程序必须通过调用 setlocale(LC_ALL, )
明确说明它希望用户对其他类别的首选语言环境设置。
在某些库例程中调用 setlocale() 通常是一个坏主意,因为作为副作用,它会影响整个程序。 保存和恢复它几乎同样糟糕:它很昂贵并且会影响在恢复设置之前碰巧运行的其他线程。
如果在编写通用模块时,您需要受语言环境影响的操作的语言环境独立版本(例如与 time.strftime() 一起使用的某些格式),您必须找到一种不使用标准库例程的方法。 更好的是说服自己使用区域设置是可以的。 只有作为最后的手段,您才应该记录您的模块与非 C
区域设置不兼容。
根据语言环境执行数字运算的唯一方法是使用此模块定义的特殊函数: atof(), atoi()[X150X], format()[X169X ], str()。
无法根据语言环境执行大小写转换和字符分类。 对于(Unicode)文本字符串,这些仅根据字符值进行,而对于字节字符串,则根据字节的ASCII值进行转换和分类,以及设置了高位的字节(即非ASCII字节) ) 永远不会被转换或被视为字符类的一部分,例如字母或空格。
23.2.2. 适用于嵌入 Python 的扩展编写者和程序
扩展模块不应该调用 setlocale(),除非是为了找出当前的语言环境。 但是由于返回值只能用于可移植地恢复它,这不是很有用(除非可能找出语言环境是否为 C
)。
当 Python 代码使用 locale 模块更改区域设置时,这也会影响嵌入应用程序。 如果嵌入应用程序不希望发生这种情况,它应该从 config.c
文件的内置模块表中删除 _locale
扩展模块(它完成所有工作),并且确保 _locale
模块不能作为共享库访问。
23.2.3. 访问消息目录
- locale.gettext(msg)
- locale.dgettext(domain, msg)
- locale.dcgettext(domain, msg, category)
- locale.textdomain(domain)
- locale.bindtextdomain(domain, dir)
locale 模块在提供此接口的系统上公开 C 库的 gettext 接口。 它由功能 gettext()
、dgettext()
、dcgettext()
、textdomain()
、bindtextdomain()
和 bind_textdomain_codeset()
组成。 这些与 gettext 模块中的相同函数类似,但使用 C 库的二进制格式作为消息目录,并使用 C 库的搜索算法来定位消息目录。
Python 应用程序通常应该不需要调用这些函数,而应该使用 gettext 代替。 此规则的一个已知例外是与内部调用 gettext()
或 dcgettext()
的其他 C 库链接的应用程序。 对于这些应用程序,可能需要绑定文本域,以便库可以正确定位其消息目录。