locale --- 國際化服務

原始碼: Lib/locale.py


locale 模組開放了對 POSIX locale 資料庫和功能的訪問。POSIX locale 機制允許程式設計師處理應用程式中的某些文化問題,而無需程式設計師瞭解軟體執行的每個國家/地區的所有細節。

locale 模組是在 _locale 模組之上實現的,後者又在可用時使用 ANSI C locale 實現。

locale 模組定義了以下異常和函式

exception locale.Error

當傳遞給 setlocale() 的 locale 未被識別時引發的異常。

locale.setlocale(category, locale=None)

如果 locale 被給出且不為 Nonesetlocale() 將修改 category 的區域設定。可用的類別在下面的資料描述中列出。locale 可以是一個 字串,或者一個由語言程式碼和編碼組成的元組。空字串指定使用者的預設設定。如果 locale 的修改失敗,則會引發 Error 異常。如果成功,將返回新的區域設定。

如果 locale 是一個元組,它將使用 locale 別名引擎轉換為 locale 名稱。語言程式碼的格式與區域設定名稱相同,但沒有編碼和 @-修飾符。語言程式碼和編碼可以是 None

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

此區域設定中未指定任何內容。

如果 locale 不同並且數字或貨幣字串為非 ASCII,該函式會臨時將 LC_CTYPE locale 設定為 LC_NUMERIC locale 或 LC_MONETARY locale。此臨時更改會影響其他執行緒。

在 3.7 版更改: 在某些情況下,該函式現在會臨時將 LC_CTYPE locale 設定為 LC_NUMERIC locale。

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 8,段落 7.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 的值。在大多數區域中,這是一個空字串。

如果區域設定不同且結果字串為非 ASCII,該函式會臨時將 LC_CTYPE 區域設定為確定請求值的類別的區域(LC_TIME, LC_NUMERIC, LC_MONETARYLC_MESSAGES)。此臨時更改會影響其他執行緒。

在 3.14 版更改: 該函式現在在某些情況下會臨時設定 LC_CTYPE 區域設定。

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',按此順序。

語言程式碼的格式與區域設定名稱相同,但沒有編碼和 @-修飾符。如果無法確定其值,語言程式碼和編碼可以為 None。"C" 區域表示為 (None, None)

自 3.11 版起棄用,將在 3.15 版中移除。

locale.getlocale(category=LC_CTYPE)

返回給定區域類別的當前設定,形式為包含語言程式碼和編碼的元組。category 可以是 LC_* 值之一,除了 LC_ALL。它預設為 LC_CTYPE

語言程式碼的格式與區域設定名稱相同,但沒有編碼和 @-修飾符。如果無法確定其值,語言程式碼和編碼可以為 None。"C" 區域表示為 (None, 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 之前、之後還是與之相等,返回負值、正值或 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 為真,轉換將使用貨幣千位分隔符和分組字串。

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 碼點。有關此變數如何可能被自動強制為 C.UTF-8 以避免容器中無效設定或透過遠端 SSH 連線傳遞的不相容設定所造成的問題,請參閱 PEP 538PEP 540

Python 內部不使用 ctype.h 中依賴於區域的字元轉換函式。相反,一個內部的 pyctype.h 提供了與區域無關的等價物,如 Py_TOLOWER

locale.LC_COLLATE

用於排序字串的區域類別。 locale 模組的 strcoll()strxfrm() 函式受此影響。

locale.LC_TIME

用於時間格式化的區域類別。time.strftime() 函式遵循這些約定。

locale.LC_MONETARY

用於格式化貨幣值的區域類別。可用選項可透過 localeconv() 函式獲得。

locale.LC_MESSAGES

用於訊息顯示的區域類別。Python 目前不支援應用程式特定的區域感知訊息。作業系統顯示的訊息,如 os.strerror() 返回的訊息,可能會受此類別的影響。

此值可能在不符合 POSIX 標準的作業系統上不可用,最顯著的是 Windows。

locale.LC_NUMERIC

用於格式化數字的區域類別。 locale 模組的 format_string()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

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

C 標準將區域定義為一個程式範圍的屬性,更改它可能相對昂貴。此外,某些實現存在缺陷,頻繁更改區域可能導致核心轉儲。這使得正確使用區域有些痛苦。

最初,當程式啟動時,無論使用者的首選區域是什麼,區域都是 C 區域。有一個例外:LC_CTYPE 類別在啟動時被更改,以將當前區域編碼設定為使用者的首選區域編碼。程式必須透過呼叫 setlocale(LC_ALL, '') 明確表示它希望對其他類別使用使用者的首選區域設定。

在某些庫例程中呼叫 setlocale() 通常是個壞主意,因為它會作為副作用影響整個程式。儲存和恢復它幾乎同樣糟糕:它代價高昂,並且會影響在設定恢復之前碰巧執行的其他執行緒。

如果在編寫通用模組時,你需要一個受區域影響的操作的與區域無關的版本(例如 time.strftime() 使用的某些格式),你將必須找到一種不使用標準庫例程的方法來完成它。更好的做法是說服自己使用區域設定是可以的。只有在萬不得已的情況下,才應記錄你的模組與非 C 區域設定不相容。

根據區域執行數字操作的唯一方法是使用此模組定義的特殊函式:atof()atoi()format_string()str()

沒有辦法根據區域設定執行大小寫轉換和字元分類。對於(Unicode)文字字串,這些操作僅根據字元值進行,而對於位元組串,轉換和分類是根據位元組的 ASCII 值進行的,高位被設定的位元組(即非 ASCII 位元組)永遠不會被轉換或被視作字元類(如字母或空白)的一部分。

區域設定名稱

區域設定名稱的格式取決於平臺,支援的區域設定集可能取決於系統配置。

在 Posix 平臺上,它通常具有以下格式 [1]

  language ["_" territory] ["." charset] ["@" modifier]

其中 language 是來自 ISO 639 的兩或三字母語言程式碼,territory 是來自 ISO 3166 的兩字母國家或地區程式碼,charset 是一個區域編碼,而 modifier 是一個指令碼名稱、語言子標籤、排序順序識別符號或其他區域修飾符(例如,“latin”、“valencia”、“stroke”和“euro”)。

在 Windows 上,支援多種格式。[2] [3] IETF BCP 47 標籤的一個子集

  language ["-" script] ["-" territory] ["." charset]
  language ["-" script] "-" territory "-" modifier

其中 languageterritory 的含義與 Posix 中的相同,script 是來自 ISO 15924 的四字母指令碼程式碼,modifier 是語言子標籤、排序順序識別符號或自定義修飾符(例如,“valencia”、“stroke”或“x-python”)。連字元 ('-') 和下劃線 ('_') 分隔符都支援。BCP 47 標籤只允許 UTF-8 編碼。

Windows 還支援以下格式的區域名稱

  language ["_" territory] ["." charset]

其中 languageterritory 是全名,例如“English”和“United States”,而 charset 是內碼表編號(例如,“1252”)或 UTF-8。此格式僅支援下劃線分隔符。

“C”區域在所有平臺上都受支援。

給擴充套件模組編寫者和嵌入 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 函式 gettextdcgettext。對於這些應用程式,可能需要繫結文字域,以便庫可以正確地定位其訊息目錄。