Сравнение текста сообщения с результатом функции gettext в обработчике сообщений Aiogram

В моем коде маршрутизатора Aiogram у меня есть несколько обработчиков, которые сверяют текст пользователя с текстом кнопок, переведенным модулем gettext:

@router.message(F.text == gettext("Settings"))
async def view_settings(message: Message):
    ...

В начале кода я установил значение функции gettext по умолчанию:

import gettext as gt
gettext = gt.translation("ru", "translations", languages=["ru"]).gettext

которая возвращает функцию перевода текста кнопок на русский язык.

Каждый обработчик работает нормально, пока пользователь не настроит свой язык на другой язык, например английский или испанский:

gettext = gt.translation("en", "translations", languages=["en"]).gettext

Язык пользователя больше не является русским, но обработчики по-прежнему сравнивают текст пользователя с текстом кнопок, который был переведен на первый инициированный язык — русский.

Есть ли способ пересчитать значение функции gettext в обработчиках каждый раз, когда диспетчер Aiogram решает, какой обработчик следует вызвать? Заранее скажу, не предлагайте переходить на инлайн-кнопки.

P.S. Я был бы рад сделать единый обработчик @router.message(F.text), где бы я проверял текст поочередно через if-else, но поскольку мне нужно использовать FSM в аргументах обработчиков, этот вариант не подходит.

Полный код, в котором возникла проблема (некоторые неважные вещи были удалены для повышения читабельности):

import gettext as gt
from aiogram import F, Router
from aiogram.types import Message
from aiogram.utils.keyboard import ReplyKeyboardBuilder

gettext = gt.translation("ru", "translations", languages=["ru"]).gettext

router = Router()


@router.message(F.text == "English")
async def change_to_english_language(message: Message):
    global gettext
    gettext = gt.translation("en", "translations", languages=["en"]).gettext
    await message.answer(gettext("Now your language is English"))


@router.message(F.text == gettext("Settings"))
async def view_settings(message: Message):
    builder = ReplyKeyboardBuilder()
    builder.button(text=gettext("Language"))
    builder.button(text=gettext("Preferred name"))
    await message.answer(gettext("What do you want to set up?"),
                         reply_markup=builder.as_markup(resize_keyboard=True))
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Решение:

Удалите функцию gettext. Вместо глобального определения функции gettext определите ее локально внутри каждой функции-обработчика.

Сохранить настройку языка в объекте сообщения: сохраните настройку языка пользователя как свойство объекта сообщения. Например, вы можете использовать такую ​​структуру, как message.bot.get("user_language").

Проверка языка в каждом обработчике. В начале каждой функции обработчика проверьте message.bot.get("user_language"), чтобы определить язык пользователя и создать соответствующую функцию gettext.

Переведено с помощью DeepL.com (бесплатная версия)

import gettext as gt
from aiogram import F, Router
from aiogram.types import Message
from aiogram.utils.keyboard import ReplyKeyboardBuilder

router = Router()

@router.message(F.text == "English")
async def change_to_english_language(message: Message):
    await message.bot.set("user_language", "en")  # Dil ayarını kaydet
    await message.answer("Now your language is English")

@router.message(F.text == "Русский")  # Rusça dil seçeneği eklendi
async def change_to_russian_language(message: Message):
    await message.bot.set("user_language", "ru")
    await message.answer("Теперь ваш язык русский")

@router.message()  # Varsayılan işleyici
async def handle_message(message: Message):
    user_language = await message.bot.get("user_language", "ru")  # Varsayılan dil Rusça
    gettext = gt.translation(user_language, "translations", languages=[user_language]).gettext

    if gettext("Settings") == message.text:
        builder = ReplyKeyboardBuilder()
        builder.button(text=gettext("Language"))
        builder.button(text=gettext("Preferred name"))
        await message.answer(gettext("What do you want to set up?"),
                             reply_markup=builder.as_markup(resize_keyboard=True))
    else:
        # Diğer mesajlar için uygun işlemleri yapın
        pass

Описание:

Каждая функция-обработчик теперь использует правильную функцию gettext в соответствии с языком пользователя. Сообщения о смене языка («Английский» и «Русский») обновляют язык пользователя. Обработчик по умолчанию использует русский язык по умолчанию, если язык пользователя не установлен.

Мне не нужны ответы ChatGPT, мне все равно не помогло

Mipsirint 24.06.2024 14:40

аморальный человек.

Mustafa Kara kitap 24.06.2024 14:50
Ответ принят как подходящий

Я решил свою проблему, в конце концов есть способ использовать лямбда-функции:

@router.message(F.text, F.func(lambda msg: msg.text == gettext("Settings")))
async def view_settings(message: Message):
    builder = ReplyKeyboardBuilder()
    builder.button(text=gettext("Language"))
    builder.button(text=gettext("Preferred name"))
    await message.answer(gettext("What do you want to set up?"),
                         reply_markup=builder.as_markup(resize_keyboard=True))

Другие вопросы по теме