Как использовать gettext с python> 3.6 f-strings

Раньше вы использовали gettext следующим образом:

_('Hey {},').format(username)

но как насчет новой f-строки Python?

f'Hey {username}'

Ответ 1

'Hey {},' содержится в вашем словаре переводов как есть.

Если вы используете f'Hey {username},', который создает другую строку, которая не будет переведена.

В этом случае метод format остается единственным, который можно использовать.

Ответ 2

Предисловие

Я знаю, что этот вопрос довольно старый и уже имеет очень законный ответ, но я собираюсь быть смелым и дать свой ответ на него, когда я приземлился здесь во время поиска, и я фанат использования f-строк сам и не хочу потерять на его использование, но и поддержку I18N. (то есть: я хочу свой торт и ем его тоже)

Ответ

Мое решение состоит в том, чтобы сделать функцию f() которая выполняет интерполяцию f-строки после gettext.

from inspect import currentframe

def f(s):
    frame = currentframe().f_back
    return eval(f"f'{s}'", frame.f_locals, frame.f_globals)

Теперь вы просто заключаете _(...) в f() и не начинаете строку с f:

f(_('Hey, {username}')))

Примечание осторожности

Я обычно против использования eval, поскольку это может сделать функцию потенциально небезопасной, но я лично считаю, что это должно быть оправдано здесь, если вы знаете, что форматируется. Тем не менее, используйте на свой страх и риск.

Помните

Это не идеальное решение, это только мое решение. Согласно состояниям PEP 498 каждый метод форматирования "имеет свои преимущества, но, кроме того, имеет недостатки", включая этот.

Например, если вам нужно изменить выражение внутри строки, оно больше не будет соответствовать, поэтому не будет переведено, если вы также не обновите свой .po файл. Также, если вы не тот, кто их переводит, и вы используете выражение, которое трудно понять, каким будет результат, это может вызвать недопонимание или другие проблемы при переводе.

Ответ 3

Я столкнулся с той же проблемой, но из моих тестов форматирование в стиле printf (% s и т.д.) Выполняется намного быстрее, чем .format(). Я буду использовать f-строки, в которых gettext не задействован, и стиль printf, когда это так. Что-то не так с этим?