locale --- 國際化服務?

源代碼: Lib/locale.py


locale 模塊開通了 POSIX 本地化數據庫和功能的訪問。POSIX 本地化機制讓程序員能夠為應用程序處理某些本地化的問題,而不需要去了解運行軟件的每個國家的全部文化特點。

locale 模塊是在 _locale 模塊的基礎上實現的,而 _locale 則又用到了 ANSI C 語言實現的本地化功能。

locale 模塊定義了以下異常和函數:

exception locale.Error?

當傳給 setlocale() 的 locale 無法識別時,會觸發異常。

locale.setlocale(category, locale=None)?

如果給定了 locale 而不是 Nonesetlocale() 會修改 category 的 locale 設置。可用的類別會在下面的數據描述中列出。locale 可以是一個字符串,也可以是兩個字符串(語言代碼和編碼)組成的可迭代對象。若為可迭代對象,則會用地區別名引擎轉換為一個地區名稱。若為空字符串則指明采用用戶的默認設置。如果 locale 設置修改失敗,會觸發 Error 異常。如果成功則返回新的 locale 設置。

如果省略 locale 或為 None,將返回 category 但當前設置。

setlocale() 在大多數系統上都不是線程安全的。應用程序通常會如下調用:

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

這會把所有類別的 locale 都設為用戶的默認設置(通常在 LANG 環境變量中指定)。如果后續 locale 沒有改動,則使用多線程應該不會產生問題。

locale.localeconv()?

以字典的形式返回本地約定的數據庫。此字典具有以下字符串作為鍵:

類別

(Windows 注冊表的)鍵

含義

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 地區,若地區不同且數字或貨幣字符為非 ASCII,則設置為 LC_MONETARY 地區。這個臨時的改變會影響到其他線程。

在 3.7 版更改: 現在在某些情況下,該函數會將 LC_CTYPE 地區設為 LC_NUMERIC 地區。

locale.nl_langinfo(option)?

以字符串形式返回一些地區相關的信息。本函數并非在所有系統都可用,而且可用的 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?

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

locale.getlocale(category=LC_CTYPE)?

以列表的形式返回指定地區類別的當前設置,結果包括 語言代碼編碼category 可以是 LC_* 之一, LC_ALL 除外。默認為 LC_CTYPE

除了 'C' 之外,語言代碼對應 RFC 1766 標準。如果 語言代碼編碼 不能確定,可為 None

locale.getpreferredencoding(do_setlocale=True)?

Return the encoding used for text data, according to user preferences. User preferences are expressed differently on different systems, and might not be available programmatically on some systems, so this function only returns a guess.

某些系統必須調用 setlocale() 才能獲取用戶偏好,所以本函數不是線程安全的。如果不需要或不希望調用 setlocale,do_setlocale 應設為 False

On Android or in the UTF-8 mode (-X utf8 option), always return 'UTF-8', the locale and the do_setlocale argument are ignored.

在 3.7 版更改: The function now always returns UTF-8 on Android or if the UTF-8 mode is enabled.

locale.normalize(localename)?

為給定的區域名稱返回標準代碼。返回的區域代碼已經格式化,可供 setlocale() 使用。 如果標準化操作失敗,則返回原名稱。

如果給出的編碼無法識別,則本函數默認采用區域代碼的默認編碼,這正類似于 setlocale()

locale.resetlocale(category=LC_ALL)?

category 的區域設為默認值。

默認設置通過調用 getdefaultlocale() 確定。category 默認為 LC_ALL

locale.strcoll(string1, string2)?

根據當前的 LC_COLLATE 設置,對兩個字符串進行比較。與其他比較函數一樣,根據 string1 位于 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 進行格式化。格式將遵循 % 運算符的約定。浮點值的小數點會按需修改。若 grouping 為 True,則還會考慮分組。

monetary 為 True,則會用到貨幣千位分隔符和分組字符串。

格式化符的處理類似 format % val ,但會考慮到當前的區域設置。

在 3.7 版更改: 增加了關鍵字參數 monetary

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

請注意,本函數的工作原理與 format_string() 類似,但只對 %char 格式符起作用。 比如 '%f''%.0f' 都是有效的格式符,但 '%f KiB' 則不是。

若想用到全部的格式化串,請采用 format_string()

3.7 版后已移除: 請改用 format_string()?。

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

根據當前的 LC_MONETARY 設置,對數字 val 進行格式化。

如果 symbol 為 True(默認值),則返回的字符串將包含貨幣符號。如果 grouping 為 True(非默認值),則會進行分組。如果 international 為 True(非默認值),將采用國際貨幣符號。

請注意,本函數對區域 “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_COLLATE?

字符串排序會用到的區域類別。 將會影響 locale 模塊的 strcoll()strxfrm() 函數。

locale.LC_TIME?

格式化時間時會用到的區域類別。 time.strftime() 函數會參考這些約定。

locale.LC_MONETARY?

格式化貨幣值時會用到的區域類別。可用值可由 localeconv() 函數獲取。

locale.LC_MESSAGES?

顯示消息時用到的區域類別。目前 Python 不支持應用定制的本地化消息。 由操作系統顯示的消息,比如由 os.strerror() 返回的消息可能會受到該類別的影響。

locale.LC_NUMERIC?

格式化數字時用到的區域類別。 locale 模塊的 format()atoi()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

背景、細節、提示、技巧和注意事項?

The C standard defines the locale as a program-wide property that may be relatively expensive to change. On top of that, some implementation are broken in such a way that frequent locale changes may cause core dumps. This makes the locale somewhat painful to use correctly.

當程序第一次啟動時,無論用戶偏好定義成什么,區域值都是 C。不過有一個例外,就是在啟動時修改 LC_CTYPE 類別,設置當前區域編碼為用戶偏好編碼。程序必須調用 setlocale(LC_ALL, '') 明確表示用戶偏好區域將設為其他類別。

若要從庫程序中調用 setlocale() ,通常這不是個好主意,因為副作用是會影響整個程序。保存和恢復區域設置也幾乎一樣糟糕:不僅代價高昂,而且會影響到恢復之前運行的其他線程。

如果是要編寫通用模塊,需要有一種不受區域設置影響的操作方式(比如某些用到 time.strftime() 的格式),將不得不尋找一種不用標準庫的方案。更好的辦法是說服自己,可以采納區域設置。只有在萬不得已的情況下,才能用文檔標注出模塊與非 C 區域設置不兼容。

根據區域設置進行數字運算的唯一方法,就是采用本模塊定義的函數:atof()atoi()format()str()

無法根據區域設置進行大小寫轉換和字符分類。對于(Unicode)文本字符串來說,這些操作都是根據字符值進行的;而對于字節符串來說,轉換和分類則是根據字節的 ASCII 值進行的,高位被置位的字節(即非 ASCII 字節)永遠不會被轉換或被視作字母或空白符之類。

針對擴展程序編寫人員和嵌入Python 運行的程序?

除了要查詢當前區域,擴展模塊不應去調用 setlocale()。但由于返回值只能用于恢復設置,所以也沒什么用(也許只能用于確認是否為 C)。

當 Python 代碼利用 locale 模塊修改區域設置時,也會影響到嵌入 Python 運行的應用程序。如果嵌入運行的程序不希望發生這種情況,則應從 config.c 文件的內置模塊表中刪除 _locale 擴展模塊(所有操作均是由它完成的),并確保 _locale 模塊不能成為一個共享庫。

訪問信息目錄?

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

在提供 gettext 接口的系統中,locale 模塊暴露出了 C 庫的接口。它由 gettext()dgettext()dcgettext()textdomain()bindtextdomain()bind_textdomain_codeset() 等函數組成。 他們與 gettext 模塊中的同名函數類似,但采用了 C 庫二進制格式的消息目錄,以及 C 庫的搜索算法來查找消息目錄。

Python 應用程序通常不需要調用這些函數,而應改用 gettext。這條規則的一個已知例外,是與附加 C 庫鏈接的應用程序,他們在內部調用了 gettext()dcgettext()。對于這些應用程序,可能有必要綁定文本域,以便庫可以準確找到他們的信息目錄。