locale — 国际化服务

源代码: Lib/locale.py


locale 模块提供对 POSIX 区域设置数据库和功能的访问。 POSIX 区域设置机制允许程序员在应用程序中处理某些文化问题,而无需程序员了解软件执行的每个国家/地区的具体细节。

locale 模块是在 _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()

以字典形式返回本地约定的数据库。此字典具有以下字符串作为键

类别

含义

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

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

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

在 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.DAY_4
locale.DAY_5
locale.DAY_6
locale.DAY_7

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

注意

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

locale.ABDAY_1
locale.ABDAY_2
locale.ABDAY_3
locale.ABDAY_4
locale.ABDAY_5
locale.ABDAY_6
locale.ABDAY_7

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

locale.MON_1
locale.MON_2
locale.MON_3
locale.MON_4
locale.MON_5
locale.MON_6
locale.MON_7
locale.MON_8
locale.MON_9
locale.MON_10
locale.MON_11
locale.MON_12

获取第 n 个月份的名称。

locale.ABMON_1
locale.ABMON_2
locale.ABMON_3
locale.ABMON_4
locale.ABMON_5
locale.ABMON_6
locale.ABMON_7
locale.ABMON_8
locale.ABMON_9
locale.ABMON_10
locale.ABMON_11
locale.ABMON_12

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

locale.RADIXCHAR

获取基数字符(小数点、小数逗号等)。

locale.THOUSEP

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

locale.YESEXPR

获取一个正则表达式,该表达式可以与 regex 函数一起使用,以识别对“是/否”问题的肯定答复。

locale.NOEXPR

获取一个正则表达式,该表达式可以与 regex(3) 函数一起使用,以识别对“是/否”问题的否定答复。

注意

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

locale.CRNCYSTR

获取货币符号,如果该符号应显示在值之前,则以“-”开头;如果该符号应显示在值之后,则以“+”开头;如果该符号应替换基数字符,则以“.”开头。

locale.ERA

获取一个字符串,该字符串描述如何在区域设置中为每个纪元计数和显示年份。

大多数区域设置没有定义此值。一个定义此值的区域设置示例是日语区域设置。在日本,传统的日期表示形式包括与当时天皇统治相对应的纪元名称。

通常,没有必要直接使用此值。在它们的格式字符串中指定 E 修饰符会导致 time.strftime() 函数使用此信息。返回字符串的格式在The Open Group Base Specifications Issue 87.3.5.2 LC_TIME C-Language Access 段落中指定。

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

尝试确定默认的区域设置并将其作为 (语言代码, 编码) 形式的元组返回。

根据 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)

返回给定区域设置类别的当前设置,以包含 语言代码编码 的序列形式。category 可以是 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.strcoll(string1, string2)

根据当前的 LC_COLLATE 设置比较两个字符串。与其他任何比较函数一样,根据 string1 是否在 string2 之前或之后排序,或者是否等于 string2,返回负值、正值或 0

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 为 true,则转换将使用货币千位分隔符和分组字符串。

处理格式说明符,如 format % val,但会考虑当前的区域设置。

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

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

根据当前的 LC_MONETARY 设置格式化数字 val

如果 symbol 为 true(默认情况),则返回的字符串包含货币符号。如果 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)

通过对 string 调用 delocalize() 的结果调用 func ,根据 LC_NUMERIC 设置将字符串转换为数字。

locale.atoi(string)

根据 LC_NUMERIC 约定,将字符串转换为整数。

locale.LC_CTYPE

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

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 函数 gettextdcgettext 的其他 C 库链接的应用程序。对于这些应用程序,可能需要绑定文本域,以便库可以正确找到其消息目录。