如何在Windows系统的Python中获取BCP-47格式的区域设置?
如何在Windows系统的Python中获取BCP-47格式的区域设置?
这个问题确实挺让人挠头的,我来给你理清楚来龙去脉和解决办法:
为什么会返回French_France.1252?
你看到的French_France其实是Windows传统的区域设置命名格式,属于旧版的标识符规范。Python的locale模块底层调用的是Windows的C标准库API,而这套API沿用了早期Windows的区域设置命名逻辑——虽然Windows从Vista开始就支持BCP-47格式,但locale模块并没有直接适配返回新格式,所以就出现了你看到的这种旧命名。至于.1252,是对应的8位代码页,属于和区域设置绑定的传统编码标识。
怎么转换成BCP-47格式?
这里有几种靠谱的方法,推荐优先用系统API的方式,避免手动映射的误差:
方法1:用ctypes直接调用Windows API(无需额外安装库)
Windows提供了专门的API来获取BCP-47格式的区域名称,我们可以用ctypes直接调用:
import ctypes # 创建缓冲区存储结果,BCP-47名称最长不会超过64字符,这里设128足够 locale_buffer = ctypes.create_unicode_buffer(128) # 调用GetUserDefaultLocaleName获取当前用户的默认区域设置BCP-47名称 ctypes.windll.kernel32.GetUserDefaultLocaleName(locale_buffer, 128) print(locale_buffer.value) # 输出类似 "fr-FR"
方法2:使用pywin32库(封装更友好)
如果你已经安装了pywin32(可以用pip install pywin32安装),可以用它封装好的函数来实现:
import win32api import win32locale # 获取当前用户的默认区域设置ID(LCID) lcid = win32api.GetUserDefaultLCID() # 把LCID转换成BCP-47格式的名称 bcp47_locale = win32locale.LCIDToLocaleName(lcid) print(bcp47_locale) # 输出 "fr-FR"
方法3:手动映射(不推荐)
如果只是临时处理已知的旧格式字符串,你可以手动维护一个映射字典,但这种方法不通用,遇到少见的区域设置容易出错,比如:
old_to_bcp47 = { "French_France": "fr-FR", "English_United States": "en-US", # 可以继续补充其他映射 } # 假设你从locale模块拿到了旧格式字符串 old_locale = "French_France" print(old_to_bcp47.get(old_locale, "未知区域设置"))
总结一下:如果要准确获取BCP-47格式,优先调用Windows原生API,避免依赖locale模块的旧格式输出。
备注:内容来源于stack exchange,提问作者Reuben Thomas




