В моем коде маршрутизатора 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))
Решение:
Удалите функцию 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 в соответствии с языком пользователя. Сообщения о смене языка («Английский» и «Русский») обновляют язык пользователя. Обработчик по умолчанию использует русский язык по умолчанию, если язык пользователя не установлен.
аморальный человек.
Я решил свою проблему, в конце концов есть способ использовать лямбда-функции:
@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))
Мне не нужны ответы ChatGPT, мне все равно не помогло