Is there a way to temporarily activate a locale within the scope of a block of code? Basically, I want to do something like this:
locale.setlocale(locale.LC_
You can write an easy and straight-forward contextmanager for this:
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)
Unsure whether you really want to do that. The locale may be global(*) to the program, so it could give a weird behaviour in a multithreaded context. Worse, the standard library documentation says:
The C standard defines the locale as a program-wide property that may be relatively expensive to change. On top of that, some implementation are broken in such a way that frequent locale changes may cause core dumps.
That being said, it is possible to build a custom context manager:
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)
Example on a French Windows:
>>> print(locale.getlocale())
('fr_FR', 'cp1252')
>>> with LocaleManager("C"):
print(locale.getlocale())
(None, None)
>>> print(locale.getlocale())
('fr_FR', 'cp1252')
I found out that Babel better fits my use case:
>>> parse_decimal('1,25', locale='nl_BE.utf8')
Decimal('1.25')
This approach is useful whenever I need to parse a Dutch decimal and doesn't require overriding any locales at all.