22.2. 语言环境—国际化服务

locale模块打开对 POSIX 语言环境数据库和Function的访问。 POSIX 语言环境机制允许程序员处理应用程序中的某些文化问题,而无需程序员知道执行软件的每个国家/locale 的所有详细信息。

locale模块是在_locale模块的顶部实现的,而_locale模块则使用 ANSI C 语言环境实现(如果有)。

locale模块定义以下异常和Function:

  • exception locale. Error

    • 无法识别传递给setlocale()的语言环境时引发的异常。
  • locale. setlocale(类别 [,语言环境])

    • 如果给出* locale 而不是None,则setlocale()修改 category *的语言环境设置。可用类别在下面的数据描述中列出。 * locale *可以是一个字符串,也可以是两个字符串的迭代(语言代码和编码)。如果是可迭代的,则使用语言环境别名引擎将其转换为语言环境名称。空字符串指定用户的默认设置。如果对语言环境的修改失败,则会引发异常Error。如果成功,则返回新的语言环境设置。

如果Ellipsis* locale None,则返回 category *的当前设置。

setlocale()在大多数系统上不是线程安全的。应用程序通常以

import locale
locale.setlocale(locale.LC_ALL, '')

这会将所有类别的语言环境设置为用户的默认设置(通常在 LANG环境变量中指定)。如果此后未更改语言环境,则使用多线程不会引起问题。

在版本 2.0 中进行了更改:添加了对* locale *参数的可迭代值的支持。

  • locale. localeconv ( )
    • 以字典的形式返回本地约定的数据库。该词典具有以下字符串作为键:
CategoryKeyMeaning
LC_NUMERIC'decimal_point'小数点字符。
'grouping'数字序列,指定'thousands_sep'的相对位置。如果序列以CHAR_MAX终止,则不会执行进一步的分组。如果序列以0结尾,则重复使用最后一个组大小。
'thousands_sep'组之间使用的字符。
LC_MONETARY'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'用于 Comments 正货币值的符号。
'negative_sign'用于 Comments 负值的符号。
'p_sign_posn/n_sign_posn'符号的位置(对于正值或负值),请参见下文。

可以将所有数值设置为CHAR_MAX,以指示此语言环境中未指定任何值。

'p_sign_posn''n_sign_posn'的可能值如下所示。

ValueExplanation
0货币和价值用括号括起来。
1该符号应位于价值和货币符号之前。
2该符号应跟随价值和货币符号。
3符号应紧接值之前。
4标志应紧随值之后。
CHAR_MAX在此语言环境中未指定任何内容。
  • locale. nl_langinfo(* option *)
    • 以字符串形式返回一些特定于语言环境的信息。此Function并非在所有系统上都可用,并且不同平台上可能的选项集也会有所不同。可能的参数值为数字,在语言环境模块中可以使用其符号常量。

nl_langinfo()Function接受以下键之一。大多数描述均来自 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 天的名称。

Note

这遵循美国的惯例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 函数一起使用的正则表达式,以识别对是/否问题的肯定回答。

Note

该表达式的语法适合 C 库中的regex()函数,该语法可能与re中使用的语法不同。

  • locale. NOEXPR

    • 获取可与 regex(3)函数一起使用的正则表达式,以识别对是/否问题的否定响应。
  • locale. CRNCYSTR

    • 获取货币符号,如果该符号应出现在值之前,则以“-”开头,如果该符号应出现在值之后,则以“”开头,否则为“。”。该符号是否应替换基数字符。
  • locale. ERA

    • 获取一个字符串,该字符串表示当前语言环境中使用的时代。

大多数语言环境未定义此值。定义此值的语言环境的一个示例是日语。在日本,日期的传统表示法包括当时皇帝统治时期的时代名称。

通常,没有必要直接使用此值。在其格式字符串中指定E修饰符会使time.strftime()函数使用此信息。未指定返回字符串的格式,因此,您不应在其他系统上假设它的知识。

  • locale. ERA_D_T_FMT

    • 获取time.strftime()的格式字符串,以特定于 locale 的基于时代的方式表示日期和时间。
  • locale. ERA_D_FMT

    • 获取time.strftime()的格式字符串,以一种特定于 locale 的基于时代的方式表示日期。
  • locale. ERA_T_FMT

    • 获取time.strftime()的格式字符串,以特定于 locale 的基于时代的方式表示时间。
  • locale. ALT_DIGITS

    • 获取最多 100 个值的表示形式,用于表示 0 到 99 的值。
  • locale. getdefaultlocale([* envvars *])

    • try确定默认的语言环境设置,并将它们以(language code, encoding)的 Tuples 形式返回。

根据 POSIX,尚未调用setlocale(LC_ALL, '')的程序将使用可移植的'C'语言环境运行。调用setlocale(LC_ALL, '')使其使用 LANG变量定义的默认语言环境。由于我们不想干扰当前的语言环境设置,因此我们以上述方式模拟了行为。

为了保持与其他平台的兼容性,不仅要测试 LANG变量,还要测试作为 envvars 参数给出的变量列表。将使用发现的第一个。 * envvars *默认为 GNU gettext 中使用的搜索路径;它必须始终包含变量名LANG。 GNU gettext 搜索路径按此 Sequences 包含'LANGUAGE''LC_ALL''LC_CTYPE''LANG'

除了代码'C'之外,语言代码对应于 RFC 1766。如果无法确定其语言代码和编码,则它们可能为None

2.0 版中的新Function。

  • locale. getlocale([* 类别])
    • 返回给定语言环境类别的当前设置,作为包含语言代码和* encoding *的序列。 类别可能是LC_*值之一,但LC_ALL除外。默认为LC_CTYPE

除了代码'C'之外,语言代码对应于 RFC 1766。如果无法确定其语言代码和编码,则它们可能为None

2.0 版中的新Function。

  • locale. getpreferredencoding([* do_setlocale *])
    • 根据用户喜好返回用于文本数据的编码。用户首选项在不同系统上的表达方式有所不同,在某些系统上可能无法以编程方式获得,因此此Function仅返回一个猜测。

在某些系统上,必须调用setlocale()以获得用户首选项,因此此函数不是线程安全的。如果不需要或不需要调用 setlocale,则应将* do_setlocale *设置为False

2.3 版的新Function。

  • locale. normalize(* localename *)
    • 返回给定语言环境名称的规范化语言环境代码。返回的语言环境代码已格式化,可与setlocale()一起使用。如果规范化失败,则原始名称将保持不变。

如果给定的编码未知,则该Function默认为语言环境代码的默认编码,就像setlocale()一样。

2.0 版中的新Function。

  • locale. resetlocale([* 类别])
    • 将* category *的语言环境设置为默认设置。

默认设置是pass调用getdefaultlocale()来确定的。 类别默认为LC_ALL

2.0 版中的新Function。

  • locale. strcoll(* string1 string2 *)

    • 根据当前的LC_COLLATE设置比较两个字符串。与其他任何比较函数一样,返回一个负值或一个正值或0,这取决于* string1 是在 string2 *之前还是之后进行排序,或者等于它。
  • locale. strxfrm(* string *)

    • 将字符串转换为可用于内置函数cmp()的字符串,并且仍返回可识别语言环境的结果。当重复比较同一字符串时,例如,可以使用此Function。整理字符串序列时。
  • locale. format(* format val * [,* grouping * [,* monetary *]])
    • 根据当前的LC_NUMERIC设置格式化数字* val 。格式遵循%运算符的约定。对于浮点值,适当时将修改小数点。如果 grouping *为 true,则还将分组考虑在内。

如果* monetary *为 true,则转换使用货币千位分隔符和分组字符串。

请注意,此Function仅适用于一个%char 说明符。对于完整格式的字符串,请使用format_string()

在版本 2.5 中进行了更改:添加了* monetary *参数。

  • locale. format_string(* format val * [,* grouping *])
    • format % val一样处理格式化说明符,但要考虑当前的语言环境设置。

2.5 版的新Function。

  • locale. currency(* val * [,* symbol * [,* grouping * [,* international *]]])
    • 根据当前的LC_MONETARY设置格式化数字* val *。

如果* symbol 为 true,则返回的字符串包含货币符号,这是默认值。如果 grouping 为 true(不是默认值),则使用该值进行分组。如果 international *为 true(这不是默认值),则使用国际货币符号。

请注意,此Function不适用于'C'语言环境,因此您必须首先passsetlocale()设置语言环境。

2.5 版的新Function。

  • locale. str(* float *)

    • 使用与内置函数str(float)相同的格式来格式化浮点数,但要考虑到小数点。
  • locale. atof(* string *)

    • 按照LC_NUMERIC设置将字符串转换为浮点数。
  • locale. atoi(* string *)

    • 按照LC_NUMERIC约定将字符串转换为整数。
  • locale. LC_CTYPE

    • 字符类型Function的语言环境类别。根据该类别的设置,处理案例的模块string的Function会更改其行为。
  • locale. LC_COLLATE

  • locale. LC_TIME

    • 时间格式的语言环境类别。函数time.strftime()遵循以下约定。
  • locale. LC_MONETARY

    • 货币值格式的语言环境类别。 localeconv()Function提供了可用的选项。
  • locale. LC_MESSAGES

    • 消息显示的语言环境类别。 Python 当前不支持特定于应用程序的区域感知消息。os 显示的消息(如os.strerror()返回的消息)可能会受到此类别的影响。
  • locale. LC_NUMERIC

    • 用于格式化数字的语言环境类别。 locale模块的Functionformat()atoi()atof()str()受该类别影响。所有其他数字格式设置操作均不受影响。
  • locale. LC_ALL

    • 所有语言环境设置的组合。如果在更改语言环境时使用了此标志,则try设置所有类别的语言环境。如果对于任何类别都失败,则根本不会更改任何类别。使用此标志检索语言环境时,将返回一个字符串,指示所有类别的设置。以后可以使用该字符串来恢复设置。
  • locale. CHAR_MAX

    • 这是一个符号常量,用于localeconv()返回的不同值。

Example:

>>> 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

22.2.1. 背景,细节,提示,技巧和警告

C 标准将语言环境定义为程序范围的属性,更改该属性可能会比较昂贵。最重要的是,某些实现被破坏,频繁的语言环境更改可能会导致核心转储。这使语言环境在正确使用时有些痛苦。

最初,启动程序时,无论用户首选的语言环境是什么,语言环境都是C语言环境。该程序必须pass调用setlocale(LC_ALL, '')明确表示要用户的首选语言环境设置。

在某些库例程中调用setlocale()通常是一个坏主意,因为它的副作用是会影响整个程序。保存和恢复它几乎是一件坏事:它很昂贵,并且会影响恢复设置之前运行的其他线程。

如果在编写通用模块的代码时,需要受语言环境影响的操作的语言环境独立版本(例如string.lower()time.strftime()所使用的某些格式),那么您将必须找到一种无需使用该方法的方法标准库例程。更令人信服的是,您可以使用语言环境设置。仅在万不得已的情况下,才应证明您的模块与非C语言环境设置不兼容。

string模块中的大小写转换Function受语言环境设置的影响。当对setlocale()函数的调用更改LC_CTYPE设置时,将重新计算变量string.lowercasestring.uppercasestring.letters。请注意,pass“ fromimport…”使用这些变量的代码,例如from string import letters不受后续setlocale()调用的影响。

根据语言环境执行数字运算的唯一方法是使用此模块定义的特殊Function:atof()atoi()format()str()

22.2.2. 对于嵌入 Python 的扩展编写器和程序

扩展模块永远不要调用setlocale(),除非要找出当前的语言环境是什么。但是,由于返回值只能用于还原它,因此并不是很有用(可能要找出语言环境是否为C)。

当 Python 代码使用locale模块更改语言环境时,这也会影响嵌入应用程序。如果嵌入式应用程序不希望发生这种情况,则应从config.c文件中的内置模块表中删除_locale扩展模块(完成所有工作),并确保_locale模块不可访问,因为共享库。

22.2.3. 访问消息目录

  • locale. gettext(* msg *)

  • locale. dgettext(* domain msg *)

  • locale. dcgettext(* domain msg category *)

  • locale. textdomain(* domain *)

  • locale. bindtextdomain(* domain dir *)

语言环境模块在提供此接口的系统上公开 C 库的 gettext 接口。它由Functiongettext()dgettext()dcgettext()textdomain()bindtextdomain()bind_textdomain_codeset()组成。这些类似于gettext模块中的相同Function,但是使用 C 库的二进制格式存储消息目录,并使用 C 库的搜索算法查找消息目录。

Python 应用程序通常应该发现不需要调用这些函数,而应该使用gettext。该规则的一个已知 exception 是与其他内部调用gettext()dcgettext()的 C 库链接的应用程序。对于这些应用程序,可能有必要绑定文本域,以便库可以正确定位其消息目录。