在我们的 Django/Python/Linux 堆栈中,我们希望根据用户的语言确定正确的区域设置。语言可能是“de”,区域设置可能是 de_DE 或 de_AT 甚至 de_CH.UTF-8 - 取决于
locale -a
返回的内容。如果出现歧义,我们将仅使用相应语言的第一个有效条目。
此区域设置字符串应用于确定正确的数字格式,例如如下所示:
locale.setlocale(locale.LC_ALL, user.language)
formattedValue = locale.format_string(f'%.{decimals}f', val=gram, grouping=True)
我们不想在应用程序中创建语言代码和区域设置字符串之间的关系 - 因此定义包含语言和区域设置字符串的字典不是我们想要的。应以一般方式检索信息。
例如,在我的本地系统上,我有以下可用区域设置:
stephan@rechenmonster:~$ locale -a
C
C.utf8
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_IT.utf8
de_LI.utf8
de_LU.utf8
en_AG
en_AG.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IL
en_IL.utf8
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZM
en_ZM.utf8
en_ZW.utf8
POSIX
stephan@rechenmonster:~$
在 python 中列出了更多 - 不仅仅是可用的:
>>> locale.locale_alias.keys()
dict_keys(['a3', 'a3_az', 'a3_az.koic', 'aa_dj', 'aa_er', 'aa_et', 'af', 'af_za', 'agr_pe', 'ak_gh', 'am', 'am_et', 'american', 'an_es', 'anp_in', 'ar', 'ar_aa', 'ar_ae', 'ar_bh', 'ar_dz', 'ar_eg', 'ar_in', 'ar_iq', 'ar_jo', 'ar_kw', 'ar_lb', 'ar_ly', 'ar_ma', 'ar_om', 'ar_qa', 'ar_sa', 'ar_sd', 'ar_ss', 'ar_sy', 'ar_tn', 'ar_ye', 'arabic', 'as', 'as_in', 'ast_es', 'ayc_pe', 'az', 'az_az', 'az_az.iso88599e', 'az_ir', 'be', 'be@latin', 'be_bg.utf8', 'be_by', 'be_by@latin', 'bem_zm', 'ber_dz', 'ber_ma', 'bg', 'bg_bg', 'bhb_in.utf8', 'bho_in', 'bho_np', 'bi_vu', 'bn_bd', 'bn_in', 'bo_cn', 'bo_in', 'bokmal', 'bokmål', 'br', 'br_fr', 'brx_in', 'bs', 'bs_ba', 'bulgarian', 'byn_er', 'c', 'c-french', 'c.ascii', 'c.en', 'c.iso88591', 'c.utf8', 'c_c', 'c_c.c', 'ca', 'ca_ad', 'ca_es', 'ca_es@valencia', 'ca_fr', 'ca_it', 'catalan', 'ce_ru', 'cextend', 'chinese-s', 'chinese-t', 'chr_us', 'ckb_iq', 'cmn_tw', 'crh_ua', 'croatian', 'cs', 'cs_cs', 'cs_cz', 'csb_pl', 'cv_ru', 'cy', 'cy_gb', 'cz', 'cz_cz', 'czech', 'da', 'da_dk', 'danish', 'dansk', 'de', 'de_at', 'de_be', 'de_ch', 'de_de', 'de_it', 'de_li.utf8', 'de_lu', 'deutsch', 'doi_in', 'dutch', 'dutch.iso88591', 'dv_mv', 'dz_bt', 'ee', 'ee_ee', 'eesti', 'el', 'el_cy', 'el_gr', 'el_gr@euro', 'en', 'en_ag', 'en_au', 'en_be', 'en_bw', 'en_ca', 'en_dk', 'en_dl.utf8', 'en_gb', 'en_hk', 'en_ie', 'en_il', 'en_in', 'en_ng', 'en_nz', 'en_ph', 'en_sc.utf8', 'en_sg', 'en_uk', 'en_us', 'en_us@euro@euro', 'en_za', 'en_zm', 'en_zw', 'en_zw.utf8', 'eng_gb', 'english', 'english.iso88591', 'english_uk', 'english_united-states', 'english_united-states.437', 'english_us', 'eo', 'eo.utf8', 'eo_eo', 'eo_us.utf8', 'eo_xx', 'es', 'es_ar', 'es_bo', 'es_cl', 'es_co', 'es_cr', 'es_cu', 'es_do', 'es_ec', 'es_es', 'es_gt', 'es_hn', 'es_mx', 'es_ni', 'es_pa', 'es_pe', 'es_pr', 'es_py', 'es_sv', 'es_us', 'es_uy', 'es_ve', 'estonian', 'et', 'et_ee', 'eu', 'eu_es', 'eu_fr', 'fa', 'fa_ir', 'fa_ir.isiri3342', 'ff_sn', 'fi', 'fi_fi', 'fil_ph', 'finnish', 'fo', 'fo_fo', 'fr', 'fr_be', 'fr_ca', 'fr_ch', 'fr_fr', 'fr_lu', 'français', 'fre_fr', 'french', 'french.iso88591', 'french_france', 'fur_it', 'fy_de', 'fy_nl', 'ga', 'ga_ie', 'galego', 'galician', 'gd', 'gd_gb', 'ger_de', 'german', 'german.iso88591', 'german_germany', 'gez_er', 'gez_et', 'gl', 'gl_es', 'greek', 'gu_in', 'gv', 'gv_gb', 'ha_ng', 'hak_tw', 'he', 'he_il', 'hebrew', 'hi', 'hi_in', 'hi_in.isciidev', 'hif_fj', 'hne', 'hne_in', 'hr', 'hr_hr', 'hrvatski', 'hsb_de', 'ht_ht', 'hu', 'hu_hu', 'hungarian', 'hy_am', 'hy_am.armscii8', 'ia', 'ia_fr', 'icelandic', 'id', 'id_id', 'ig_ng', 'ik_ca', 'in', 'in_id', 'is', 'is_is', 'iso-8859-1', 'iso-8859-15', 'iso8859-1', 'iso8859-15', 'iso_8859_1', 'iso_8859_15', 'it', 'it_ch', 'it_it', 'italian', 'iu', 'iu_ca', 'iu_ca.nunacom8', 'iw', 'iw_il', 'iw_il.utf8', 'ja', 'ja_jp', 'ja_jp.euc', 'ja_jp.mscode', 'ja_jp.pck', 'japan', 'japanese', 'japanese-euc', 'japanese.euc', 'jp_jp', 'ka', 'ka_ge', 'ka_ge.georgianacademy', 'ka_ge.georgianps', 'ka_ge.georgianrs', 'kab_dz', 'kk_kz', 'kl', 'kl_gl', 'km_kh', 'kn', 'kn_in', 'ko', 'ko_kr', 'ko_kr.euc', 'kok_in', 'korean', 'korean.euc', 'ks', 'ks_in', '[email protected]', 'ku_tr', 'kw', 'kw_gb', 'ky', 'ky_kg', 'lb_lu', 'lg_ug', 'li_be', 'li_nl', 'lij_it', 'lithuanian', 'ln_cd', 'lo', 'lo_la', 'lo_la.cp1133', 'lo_la.ibmcp1133', 'lo_la.mulelao1', 'lt', 'lt_lt', 'lv', 'lv_lv', 'lzh_tw', 'mag_in', 'mai', 'mai_in', 'mai_np', 'mfe_mu', 'mg_mg', 'mhr_ru', 'mi', 'mi_nz', 'miq_ni', 'mjw_in', 'mk', 'mk_mk', 'ml', 'ml_in', 'mn_mn', 'mni_in', 'mr', 'mr_in', 'ms', 'ms_my', 'mt', 'mt_mt', 'my_mm', 'nan_tw', 'nb', 'nb_no', 'nds_de', 'nds_nl', 'ne_np', 'nhn_mx', 'niu_nu', 'niu_nz', 'nl', 'nl_aw', 'nl_be', 'nl_nl', 'nn', 'nn_no', 'no', 'no@nynorsk', 'no_no', 'no_no.iso88591@bokmal', 'no_no.iso88591@nynorsk', 'norwegian', 'nr', 'nr_za', 'nso', 'nso_za', 'ny', 'ny_no', 'nynorsk', 'oc', 'oc_fr', 'om_et', 'om_ke', 'or', 'or_in', 'os_ru', 'pa', 'pa_in', 'pa_pk', 'pap_an', 'pap_aw', 'pap_cw', 'pd', 'pd_de', 'pd_us', 'ph', 'ph_ph', 'pl', 'pl_pl', 'polish', 'portuguese', 'portuguese_brazil', 'posix', 'posix-utf2', 'pp', 'pp_an', 'ps_af', 'pt', 'pt_br', 'pt_pt', 'quz_pe', 'raj_in', 'ro', 'ro_ro', 'romanian', 'ru', 'ru_ru', 'ru_ua', 'rumanian', 'russian', 'rw', 'rw_rw', 'sa_in', 'sat_in', 'sc_it', 'sd', 'sd_in', '[email protected]', 'sd_pk', 'se_no', 'serbocroatian', 'sgs_lt', 'sh', 'sh_ba.iso88592@bosnia', 'sh_hr', 'sh_hr.iso88592', 'sh_sp', 'sh_yu', 'shn_mm', 'shs_ca', 'si', 'si_lk', 'sid_et', 'sinhala', 'sk', 'sk_sk', 'sl', 'sl_cs', 'sl_si', 'slovak', 'slovene', 'slovenian', 'sm_ws', 'so_dj', 'so_et', 'so_ke', 'so_so', 'sp', 'sp_yu', 'spanish', 'spanish_spain', 'sq', 'sq_al', 'sq_mk', 'sr', 'sr@cyrillic', 'sr@latn', 'sr_cs', 'sr_cs.iso88592@latn', 'sr_cs@latn', 'sr_me', 'sr_rs', 'sr_rs@latn', 'sr_sp', 'sr_yu', 'sr_yu.cp1251@cyrillic', 'sr_yu.iso88592', 'sr_yu.iso88595', 'sr_yu.iso88595@cyrillic', 'sr_yu.microsoftcp1251@cyrillic', 'sr_yu.utf8', 'sr_yu.utf8@cyrillic', 'sr_yu@cyrillic', 'ss', 'ss_za', 'st', 'st_za', 'sv', 'sv_fi', 'sv_se', 'sw_ke', 'sw_tz', 'swedish', 'szl_pl', 'ta', 'ta_in', 'ta_in.tscii', 'ta_in.tscii0', 'ta_lk', 'tcy_in.utf8', 'te', 'te_in', 'tg', 'tg_tj', 'th', 'th_th', 'th_th.tactis', 'th_th.tis620', 'thai', 'the_np', 'ti_er', 'ti_et', 'tig_er', 'tk_tm', 'tl', 'tl_ph', 'tn', 'tn_za', 'to_to', 'tpi_pg', 'tr', 'tr_cy', 'tr_tr', 'ts', 'ts_za', 'tt', 'tt_ru', 'tt_ru.tatarcyr', 'tt_ru@iqtelif', 'turkish', 'ug_cn', 'uk', 'uk_ua', 'univ', 'universal', 'universal.utf8@ucs4', 'unm_us', 'ur', 'ur_in', 'ur_pk', 'uz', 'uz_uz', 'uz_uz@cyrillic', 've', 've_za', 'vi', 'vi_vn', 'vi_vn.tcvn', 'vi_vn.tcvn5712', 'vi_vn.viscii', 'vi_vn.viscii111', 'wa', 'wa_be', 'wae_ch', 'wal_et', 'wo_sn', 'xh', 'xh_za', 'yi', 'yi_us', 'yo_ng', 'yue_hk', 'yuw_pg', 'zh', 'zh_cn', 'zh_cn.big5', 'zh_cn.euc', 'zh_hk', 'zh_hk.big5hk', 'zh_sg', 'zh_sg.gbk', 'zh_tw', 'zh_tw.euc', 'zh_tw.euctw', 'zu', 'zu_za'])
>>>
所以我想这归结为Python中可用的
locale -a
的输出。我现在基本上找到了这样做的方法:
locale -a
的子进程并获取调用的输出locale.locale_alias
获取 python 中的所有语言环境,过滤相关语言,并使用 locale.set_locale()
测试每个条目,并使用第一个不会引发错误的条目。这真的是唯一的两个选择吗?难道就没有更好的办法了吗?
我最终像这样解决了它 - 尽管最初不是我首选的解决方案...... 导入子流程
from common.eppaLogger import getEppaLogger
logger = getEppaLogger()
def get_active_locales():
# Get all active locales on the system using the `locale -a` command
try:
result = subprocess.run(["locale", "-a"], capture_output=True, text=True, check=True)
active_locales = result.stdout.splitlines() # Split by line to get the list of locales
return active_locales
except subprocess.CalledProcessError as e:
logger.error(str(e))
return []