使用上下文管理器临时覆盖区域设置



有没有办法在代码块范围内临时激活语言环境?基本上,我想做这样的事情:

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')

最新更新