Temporarily override locale with a context manager

前端 未结 3 911
有刺的猬
有刺的猬 2021-01-20 18:36

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_         


        
相关标签:
3条回答
  • 2021-01-20 18:57

    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)
    
    0 讨论(0)
  • 2021-01-20 19:04

    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')
    
    0 讨论(0)
  • 2021-01-20 19:16

    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.

    0 讨论(0)
提交回复
热议问题