locale — 国际化服务

源代码: Lib/locale.py


locale 模块可以访问 POSIX 本地数据库和功能。POSIX 本地机制允许程序员在应用程序中处理某些文化问题,而无需程序员了解软件执行的每个国家/地区的所有具体信息。

locale 模块是在 _locale 模块的基础上实现的,而该模块又使用 ANSI C 本地实现(如果可用)。

locale 模块定义了以下异常和函数

exception locale.Error

当传递给 setlocale() 的本地未被识别时引发的异常。

locale.setlocale(category, locale=None)

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

如果省略区域设置None,则返回类别的当前设置。

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

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

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

locale.localeconv()

返回本地惯例数据库作为字典。此字典具有以下字符串作为键

类别

含义

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'

用于注释正货币值的符号。

'negative_sign'

用于注释负货币值的符号。

'p_sign_posn/n_sign_posn'

符号的位置(对于正值和负值),见下文。

所有数字值都可以设置为CHAR_MAX,以表示此区域设置中未指定任何值。

下面给出了'p_sign_posn''n_sign_posn'的可能值。

说明

0

货币和值用括号括起来。

1

符号应位于值和货币符号之前。

2

符号应位于值和货币符号之后。

3

符号应紧挨在值之前。

4

符号应紧挨在值之后。

CHAR_MAX

此区域设置中未指定任何内容。

此函数会暂时将 LC_CTYPE 区域设置设置为 LC_NUMERIC 区域设置或 LC_MONETARY 区域设置(如果区域设置不同且数字或货币字符串为非 ASCII)。此临时更改会影响其他线程。

3.7 版中已更改: 此函数现在会在某些情况下将 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 格式表示时间。

locale.DAY_1
locale.DAY_2
locale.DAY_3
locale.星期_4
locale.星期_5
locale.星期_6
locale.星期_7

获取星期中的第 n 天的名称。

注意

这遵循美国的惯例,即 星期_1 是星期日,而不是国际惯例(ISO 8601),即星期一是星期中的第一天。

locale.星期一_1
locale.星期一_2
locale.星期一_3
locale.星期一_4
locale.星期一_5
locale.星期一_6
locale.星期一_7

获取星期中的第 n 天的缩写名称。

locale.一月_1
locale.一月_2
locale.一月_3
locale.一月_4
locale.一月_5
locale.一月_6
locale.一月_7
locale.一月_8
locale.星期一_9
locale.星期一_10
locale.星期一_11
locale.星期一_12

获取第 n 个月的名称。

locale.星期一_1
locale.星期一_2
locale.星期一_3
locale.星期一_4
locale.星期一_5
locale.星期一_6
locale.星期一_7
locale.星期一_8
locale.星期一_9
locale.星期一_10
locale.星期一_11
locale.星期一_12

获取第 n 个月的缩写名称。

locale.基数字符

获取基数字符(十进制点、十进制逗号等)。

locale.千位分隔符

获取千位分隔符(三位数字一组)。

locale.肯定表达式

获取一个正则表达式,该表达式可与 regex 函数配合使用,以识别对是非问题做出的肯定回答。

locale.NOEXPR

获取一个正则表达式,该表达式可与 regex(3) 函数结合使用,以识别对是非问题的否定响应。

注意

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

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

获取用于表示值 0 至 99 的最多 100 个值的表示形式。

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

自 3.11 版弃用,将在 3.15 版中删除。

locale.getlocale(category=LC_CTYPE)

返回给定区域设置类别当前设置,作为包含语言代码编码的序列。类别可以是 LC_* 值之一,但 LC_ALL 除外。它的默认值为 LC_CTYPE

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

locale.getpreferredencoding(do_setlocale=True)

根据用户偏好,返回用于文本数据的 区域设置编码。用户偏好因系统而异,并且在某些系统上可能无法通过编程获得,因此此函数仅返回猜测值。

在某些系统上,需要调用 setlocale() 来获取用户偏好,因此此函数不是线程安全的。如果不需要或不希望调用 setlocale,则应将 do_setlocale 设置为 False

在 Android 上或如果启用了 Python UTF-8 模式,则始终返回 'utf-8'区域设置编码do_setlocale 参数将被忽略。

Python 预初始化 配置 LC_CTYPE 区域设置。另请参阅 文件系统编码和错误处理程序

在 3.7 版中更改:现在,此函数在 Android 上或如果启用了 Python UTF-8 模式,则始终返回 "utf-8"

locale.getencoding()

获取当前 区域设置编码

  • 在 Android 和 VxWorks 上,返回 "utf-8"

  • 在 Unix 上,返回当前 LC_CTYPE 区域设置的编码。如果 nl_langinfo(CODESET) 返回空字符串,则返回 "utf-8":例如,如果当前 LC_CTYPE 区域设置不受支持。

  • 在 Windows 上,返回 ANSI 代码页。

Python 预初始化 配置 LC_CTYPE 区域设置。另请参阅 文件系统编码和错误处理程序

此函数类似于 getpreferredencoding(False),但此函数忽略 Python UTF-8 模式

在版本 3.11 中添加。

locale.normalize(localename)

返回给定区域设置名称的规范化区域设置代码。返回的区域设置代码的格式适用于 setlocale()。如果规范化失败,则返回原始名称,不作任何更改。

如果给定的编码未知,则该函数会像 setlocale() 一样,默认为区域设置代码的默认编码。

locale.resetlocale(category=LC_ALL)

category 的区域设置设置为默认设置。

默认设置通过调用 getdefaultlocale() 来确定。category 默认为 LC_ALL

自版本 3.11 起弃用,将在版本 3.13 中移除。

locale.strcoll(string1, string2)

根据当前 LC_COLLATE 设置比较两个字符串。与任何其他比较函数一样,返回负值、正值或 0,具体取决于 string1string2 之前还是之后,或者是否等于 string2

locale.strxfrm(string)

将一个字符串转换为可用于区域设置感知比较的字符串。例如,strxfrm(s1) < strxfrm(s2) 等效于 strcoll(s1, s2) < 0。当对同一字符串重复比较时,可以使用此函数,例如对一系列字符串进行整理时。

locale.format_string(format, val, grouping=False, monetary=False)

根据当前的 LC_NUMERIC 设置对数字 val 进行格式化。格式遵循 % 运算符的约定。对于浮点数,如果合适,则修改小数点。如果 groupingTrue,则还考虑分组。

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

format % val 中的形式处理格式化说明符,但考虑当前语言环境设置。

在版本 3.7 中更改:添加了 monetary 关键字参数。

locale.currency(val, symbol=True, grouping=False, international=False)

根据当前 LC_MONETARY 设置对数字 val 进行格式化。

如果 symbol 为真(这是默认值),则返回的字符串包括货币符号。如果 groupingTrue(这不是默认值),则对值进行分组。如果 internationalTrue(这不是默认值),则使用国际货币符号。

注意

此函数不适用于“C”语言环境,因此必须先通过 setlocale() 设置语言环境。

locale.str(float)

使用与内置函数 str(float) 相同的格式对浮点数进行格式化,但考虑小数点。

locale.delocalize(string)

按照 LC_NUMERIC 设置将字符串转换为标准化数字字符串。

在版本 3.5 中添加。

locale.localize(string, grouping=False, monetary=False)

按照 LC_NUMERIC 设置将标准化数字字符串转换为格式化字符串。

在版本 3.10 中添加。

locale.atof(string, func=float)

按照 LC_NUMERIC 设置将字符串转换为数字,方法是在对 string 调用 delocalize() 之后,对调用结果调用 func

locale.atoi(string)

按照 LC_NUMERIC 约定将字符串转换为整数。

locale.LC_CTYPE

字符类型函数的区域设置类别。最重要的是,此类别定义文本编码,即如何将字节解释为 Unicode 代码点。请参阅 PEP 538PEP 540,了解此变量如何自动强制转换为 C.UTF-8,以避免容器中无效设置或通过远程 SSH 连接传递的不兼容设置所造成的问题。

Python 内部不使用 ctype.h 中与区域设置相关的字符转换函数。相反,内部 pyctype.h 提供了与区域设置无关的等效项,例如 Py_TOLOWER

locale.LC_COLLATE

用于对字符串进行排序的区域设置类别。受 strcoll()strxfrm() 函数的影响,这两个函数属于 locale 模块。

locale.LC_TIME

用于对时间进行格式化的区域设置类别。函数 time.strftime() 遵循这些约定。

locale.LC_MONETARY

用于对货币值进行格式化的区域设置类别。可通过 localeconv() 函数获取可用的选项。

locale.LC_MESSAGES

用于显示消息的区域设置类别。Python 目前不支持特定于应用程序的与区域设置相关的消息。操作系统显示的消息(例如 os.strerror() 返回的消息)可能会受到此类别的影响。

此值可能在不符合 POSIX 标准的操作系统(尤其是 Windows)上不可用。

locale.LC_NUMERIC

用于对数字进行格式化的区域设置类别。函数 format_string()atoi()atof()str()locale 模块中此类别的影响。所有其他数字格式化操作不受影响。

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

背景、详细信息、提示、技巧和注意事项

C 标准将区域设置定义为程序范围的属性,更改起来可能比较昂贵。最重要的是,某些实现已损坏,以至于频繁更改区域设置可能会导致核心转储。这使得区域设置的使用变得有些痛苦。

最初,当启动程序时,区域设置是 C 区域设置,无论用户的首选区域设置是什么。有一个例外:LC_CTYPE 类别在启动时更改,以将当前区域设置编码设置为用户的首选区域设置编码。程序必须明确表示它希望通过调用 setlocale(LC_ALL, '') 来获取其他类别的用户首选区域设置。

通常不建议在某些库例程中调用 setlocale(),因为作为副作用,它会影响整个程序。保存和还原它几乎同样糟糕:它很昂贵,并且会影响在设置还原之前碰巧运行的其他线程。

如果在为一般用途编写模块时,您需要区域设置无关的操作版本,该操作受区域设置影响(例如与 time.strftime() 一起使用的某些格式),您将不得不找到一种方法来执行此操作而不使用标准库例程。更重要的是,让自己相信使用区域设置是正确的。只有在最后的手段下,您才应该记录您的模块与非 C 区域设置不兼容。

执行符合区域设置的数字运算的唯一方法是使用此模块定义的特殊函数:atof()atoi()format_string()str()

无法根据区域设置执行大小写转换和字符分类。对于(Unicode)文本字符串,这些操作仅根据字符值执行,而对于字节字符串,转换和分类根据字节的 ASCII 值执行,并且高位已设置(即非 ASCII 字节)的字节永远不会转换或被视为字母或空格等字符类的一部分。

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

扩展模块绝不应调用setlocale(),除非要找出当前区域设置。但由于返回值只能便携式地用于还原它,因此这并不是很有用(除非可能要找出区域设置是否为 C)。

当 Python 代码使用locale模块来更改区域设置时,这也将影响嵌入式应用程序。如果嵌入式应用程序不希望发生这种情况,则应从config.c文件中的内置模块表中移除_locale扩展模块(执行所有工作),并确保_locale模块不可作为共享库访问。

访问消息目录

locale.gettext(msg)
locale.dgettext(domain, msg)
locale.dcgettext(domain, msg, category)
locale.textdomain(domain)
locale.bindtextdomain(domain, dir)
locale.bind_textdomain_codeset(domain, codeset)

locale 模块在提供此接口的系统上公开 C 库的 gettext 接口。它由以下函数组成:gettext()dgettext()dcgettext()textdomain()bindtextdomain()bind_textdomain_codeset()。这些函数与 gettext 模块中的同名函数类似,但使用 C 库的消息目录二进制格式和 C 库的搜索算法来查找消息目录。

Python 应用程序通常不需要调用这些函数,而应使用 gettext。此规则的一个已知例外是链接到其他 C 库的应用程序,这些 C 库在内部调用 C 函数 gettextdcgettext。对于这些应用程序,可能需要绑定文本域,以便库可以正确找到其消息目录。