Aiogram消息处理器中gettext翻译值动态更新问题求助
解决Aiogram动态语言切换下的消息匹配问题
问题根源
你的代码中,消息处理器的匹配条件F.text == gettext("Settings")是在程序启动时就计算完成的,后续修改全局gettext变量不会更新这个条件里的匹配值——因为装饰器参数在模块加载阶段就已经固定,不会随用户语言切换重新计算。
解决方案:自定义过滤器实现动态匹配
我们需要为每个用户单独存储语言偏好,并通过自定义过滤器在每次处理消息时,动态获取对应用户语言的翻译文本,再与用户输入匹配。
1. 存储用户语言偏好与翻译缓存
用字典记录用户语言,同时缓存翻译实例避免重复加载:
import gettext as gt from aiogram import F, Router from aiogram.types import Message from aiogram.utils.keyboard import ReplyKeyboardBuilder from aiogram.filters import BaseFilter # 存储用户语言:key为用户ID,value为语言代码 user_languages = {} # 缓存翻译实例,提升性能 translations_cache = {} router = Router() def get_translator(lang: str) -> callable: """获取指定语言的翻译函数,优先读取缓存""" if lang not in translations_cache: translations_cache[lang] = gt.translation(lang, "translations", languages=[lang]).gettext return translations_cache[lang]
2. 编写自定义匹配过滤器
这个过滤器会根据用户当前语言动态生成翻译文本,再与输入对比:
class TextMatchesTranslation(BaseFilter): def __init__(self, translation_key: str): self.translation_key = translation_key async def __call__(self, message: Message) -> bool: # 获取用户当前语言,默认俄语 user_lang = user_languages.get(message.from_user.id, "ru") # 获取对应翻译函数 trans = get_translator(user_lang) # 对比用户输入和翻译后的文本 return message.text == trans(self.translation_key)
3. 修改处理器使用自定义过滤器
替换原来的静态匹配条件,改用自定义过滤器:
@router.message(F.text == "English") async def change_to_english_language(message: Message): # 更新用户语言存储 user_languages[message.from_user.id] = "en" trans = get_translator("en") await message.answer(trans("Now your language is English")) @router.message(TextMatchesTranslation("Settings")) async def view_settings(message: Message): user_lang = user_languages.get(message.from_user.id, "ru") trans = get_translator(user_lang) builder = ReplyKeyboardBuilder() builder.button(text=trans("Language")) builder.button(text=trans("Preferred name")) await message.answer(trans("What do you want to set up?"), reply_markup=builder.as_markup(resize_keyboard=True))
4. 兼容FSM使用
如果需要结合FSM状态,只需将自定义过滤器与FSM过滤器并列使用:
from aiogram.fsm.context import FSMContext from aiogram.filters import StateFilter @router.message(StateFilter(YourState), TextMatchesTranslation("Settings")) async def view_settings_in_state(message: Message, state: FSMContext): # 业务逻辑同前 ...
关键说明
- 不再依赖全局
gettext变量,为每个用户动态获取对应语言的翻译函数 - 翻译实例缓存避免了重复加载翻译文件的性能损耗
- 自定义过滤器完全兼容Aiogram的调度机制,包括FSM状态判断
内容的提问来源于stack exchange,提问作者Mipsirint
相关产品推荐
相关产品推荐

