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 被給出且不為
None
,setlocale()
將修改 category 的區域設定。可用的類別在下面的資料描述中列出。locale 可以是一個 字串,或者一個由語言程式碼和編碼組成的元組。空字串指定使用者的預設設定。如果 locale 的修改失敗,則會引發Error
異常。如果成功,將返回新的區域設定。如果 locale 是一個元組,它將使用 locale 別名引擎轉換為 locale 名稱。語言程式碼的格式與區域設定名稱相同,但沒有編碼和
@
-修飾符。語言程式碼和編碼可以是None
。如果 locale 省略或為
None
,則返回 category 的當前設定。在大多數系統上,
setlocale()
不是執行緒安全的。應用程式通常以呼叫以下程式碼開始import locale locale.setlocale(locale.LC_ALL, '')
這將所有類別的區域設定設為使用者的預設設定(通常在
LANG
環境變數中指定)。如果之後不更改區域設定,使用多執行緒應該不會導致問題。
- locale.localeconv()¶
以字典形式返回本地慣例的資料庫。該字典包含以下字串作為鍵
類別
鍵
含義
'decimal_point'
小數點字元。
'grouping'
指定
'thousands_sep'
預期出現位置的相對位置的數字序列。如果序列以CHAR_MAX
結尾,則不再進行分組。如果序列以0
結尾,則重複使用最後一個組的大小。'thousands_sep'
組之間使用的字元。
'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)
函式一起使用的正則表示式,用於識別對“是/否”問題的否定回答。
- 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_MONETARY
或LC_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。格式遵循%
運算子的約定。對於浮點值,如果適用,小數點將被修改。如果 grouping 為True
,還會考慮分組。如果 monetary 為真,轉換將使用貨幣千位分隔符和分組字串。
像
format % val
一樣處理格式說明符,但會考慮當前的區域設定。在 3.7 版更改: 增加了 monetary 關鍵字引數。
- locale.currency(val, symbol=True, grouping=False, international=False)¶
根據當前的
LC_MONETARY
設定格式化數字 val。如果 symbol 為真(預設值),返回的字串將包含貨幣符號。如果 grouping 為
True
(非預設值),將對值進行分組。如果 international 為True
(非預設值),將使用國際貨幣符號。備註
此函式在“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 538 和 PEP 540。Python 內部不使用
ctype.h
中依賴於區域的字元轉換函式。相反,一個內部的pyctype.h
提供了與區域無關的等價物,如Py_TOLOWER
。
- 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
其中 language 和 territory 的含義與 Posix 中的相同,script 是來自 ISO 15924 的四字母指令碼程式碼,modifier 是語言子標籤、排序順序識別符號或自定義修飾符(例如,“valencia”、“stroke”或“x-python”)。連字元 ('-'
) 和下劃線 ('_'
) 分隔符都支援。BCP 47 標籤只允許 UTF-8 編碼。
Windows 還支援以下格式的區域名稱
language ["_" territory] ["." charset]
其中 language 和 territory 是全名,例如“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 函式 gettext
或 dcgettext
。對於這些應用程式,可能需要繫結文字域,以便庫可以正確地定位其訊息目錄。