使用Python Telegram Bot的Message Handler无法切换状态问题
问题分析与解决方案
你的代码无法切换状态进入name方法,主要有两个核心问题及对应解决方式:
1. 旧写法中range(1)的错误
你之前用NAME = range(1)时,range(1)是一个range对象(输出为range(0,1)),而非整数0。此时states字典的键是这个range对象,但chat函数返回的是整数0,两者类型不匹配,直接导致状态无法切换。
解决方式:改用整数作为状态标识符,或正确使用枚举成员(而非枚举的value)。
2. 枚举使用的优化(当前代码的潜在问题)
当前代码中你返回Pos.NAME.value(整数0),states的键也是Pos.NAME.value(整数0),理论上匹配,但枚举value可能存在隐式类型适配问题。更可靠的写法是直接使用枚举成员作为状态标识符:
修改后的完整代码:
from enum import Enum from telegram import Update from telegram.ext import ( Application, CommandHandler, MessageHandler, filters, ConversationHandler, ) class Pos(Enum): NAME = 0 async def chat(update: Update, context) -> Pos: await update.message.reply_text('Insert your name:)') return Pos.NAME async def name(update: Update, context) -> int: name = update.message.text await update.message.reply_text(f'Your name is {name}!') return ConversationHandler.END def main() -> None: application = Application.builder().token("MY_TOKEN").build() application.add_handler( ConversationHandler( entry_points=[CommandHandler("chat", chat)], states={ # 直接使用枚举成员作为状态键 Pos.NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, name)] }, fallbacks=[], ) ) application.run_polling() if __name__ == "__main__": main()
额外调试方案
如果问题仍存在,可添加fallback handler排查状态是否正确切换:
async def fallback(update: Update, context): await update.message.reply_text("未匹配到当前状态的处理逻辑") return ConversationHandler.END # 在ConversationHandler的fallbacks参数中添加该handler fallbacks=[MessageHandler(filters.ALL, fallback)]
若用户回复文本时触发fallback,说明状态未正确存储,可尝试显式指定内存持久化:
from telegram.ext import MemoryPersistence def main() -> None: persistence = MemoryPersistence() application = Application.builder().token("MY_TOKEN").persistence(persistence).build() # 其余代码保持不变
内容的提问来源于stack exchange,提问作者AnDré
相关产品推荐
相关产品推荐

