有没有办法在代码块范围内临时激活语言环境?基本上,我想做这样的事情:
locale.setlocale(locale.LC_NUMERIC, 'nl_BE.utf8')
喜欢这个:
with override_locale(locale.LC_NUMERIC, 'nl_BE.utf8'):
# Stuff here
这样我还可以避免使用setlocale
时可能出现的任何线程安全问题。我的用例是解析上传的文件,其中小数点使用逗号而不是句点作为小数分隔符(例如 1,25 而不是 1.25(。
您可以为此编写一个简单明了的上下文管理器:
from locale import getlocale, setlocale
from contextlib import contextmanager
@contextmanager
def override_locale(category, locale_string):
prev_locale_string = getlocale(category)
setlocale(category, locale_string)
yield
setlocale(category, prev_locale_string)
我发现 Babel 更适合我的用例:
>>> parse_decimal('1,25', locale='nl_BE.utf8')
Decimal('1.25')
每当我需要解析荷兰语十进制并且根本不需要覆盖任何区域设置时,此方法都很有用。
不确定你是否真的想这样做。语言环境对程序来说可能是全局的(*(,因此它可能在多线程上下文中给出奇怪的行为。更糟糕的是,标准库文档说:
C 标准将区域设置定义为程序范围的属性,更改该属性的成本可能相对较高。最重要的是,某些实现被破坏,频繁的区域设置更改可能会导致核心转储。
话虽如此,可以构建一个自定义上下文管理器:
class LocaleManager:
def __init__(self, localename):
self.name = localename
def __enter__(self):
self.orig = locale.setlocale(locale.LC_CTYPE)
locale.setlocale(locale.LC_ALL, self.name)
def __exit__(self, exc_type, exc_value, traceback):
locale.setlocale(locale.LC_ALL, self.orig)
法式窗户上的示例:
>>> print(locale.getlocale())
('fr_FR', 'cp1252')
>>> with LocaleManager("C"):
print(locale.getlocale())
(None, None)
>>> print(locale.getlocale())
('fr_FR', 'cp1252')