[Python-ideas] Combine f-strings with i18n
Stephen J. Turnbull
turnbull.stephen.fw at u.tsukuba.ac.jp
Sun Sep 16 04:35:09 EDT 2018
Hans Polak writes:
> The second problem is that I need to translate strings on the fly.
I don't understand what that means. gettext() does exactly that. Do
you mean you need to switch languages on the fly?
> I propose to add a f''.language() method to the f-string format.
>
> Rationale:
>
> More pythonic.
I don't think so, since as Chris points out, an f-string is an
expression whose value is a str, with the values of the locals already
interpolated in the string. You'd need a lot of magic in the compiler
to make this work.
> At this moment, _('').format() is the way to go, so I
> would need to wrap another call around that: T(_(''), args, 'es_ES')
> <===This is an ugly hack.
>
> # Set the _() function to return the same string
>
> _ = lambda s: s
>
> es = gettext.translation('myapplication', languages=['es_ES'])
If, as I guessed, you want to change languages on the fly, I would
advise to make a hash table of languages used so far, and add
translation tables to it on the fly as new languages are requested.
Or, if space is at a premium, a LRU cache of tables.
> def T(translatable_string, args_dictionary = None, language = None)
>
> if 'es_ES' == language:
>
> # Return translated, formatted string
>
> return es.gettext(translatable_string).format(args)
>
>
> # Default, return formatted string
>
> return translatable_string.format(args)
Then you can replace this with
# Use duck-typing of gettext.translation objects
class NullTranslation:
def __init__(self):
self.gettext = lambda s: s
def get_gettext(language, translation={'C': NullTranslation()}):
if language not in translation:
translation[language] = \
gettext.translation('myapplication', languages=[language])
return translation[language].gettext
and
# This could be one line, but I guess in many cases you're likely
# to use use the gettext function repeatedly. Also, use of the
# _() idiom marks translatable string for translators.
_ = get_gettext(language)
_(translatable_string).format(key=value...)
instead of T(translatable_string, args, language) which isn't great
style (the names "T" and "args" are not very evocative). It's a
little more code, but it doesn't require changing the semantics of
existing Python code, and is prettier than your T() function IMO.
Steve
More information about the Python-ideas
mailing list