我正在开发一个 Telegram 机器人,它使用
python-telegram-bot
库和 IMDbPY
推荐电影。我使用 asyncio
从同步代码切换为异步代码,以更有效地处理等待时间,但遇到以下错误:
RuntimeError: This event loop is already running
此外,尝试关闭事件循环时会发生另一个错误:
RuntimeError: Cannot close a running event loop
我正在使用 Python 3.12 和
asyncio.run(main())
来启动机器人。我对异步编程相当陌生,所以我不完全确定如何在这种情况下正确处理事件循环。
当我尝试使用await
application.run_polling()
运行机器人时,会发生错误。我的主要功能是用asyncio.run(main())
设置的。这是我的代码的简化版本:
import asyncio
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters
from imdb import IMDb
async def main():
application = ApplicationBuilder().token("YOUR_BOT_TOKEN").build()
# Handlers
application.add_handler(CommandHandler("start", init))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, genres_selected))
await application.run_polling() # Issue occurs here
await application.idle()
if __name__ == '__main__':
asyncio.run(main())
我知道
asyncio.run()
创建了自己的事件循环,但我不确定如何管理它,因为 ApplicationBuilder
也使用 asyncio
。
如何正确运行机器人而不遇到此错误?我应该避免将
asyncio.run()
与 run_polling()
一起使用,还是有更好的方法来处理这种情况下的异步任务?
任何见解将不胜感激!
我尝试从
start_polling()
切换到 run_polling()
,因为我认为这可能会解决问题,但错误仍然存在。我希望机器人能够正常运行并开始轮询消息,但相反,我收到了有关事件循环多次运行的错误。
我已经研究过使用
asyncio.get_event_loop()
等解决方案,但我仍然遇到事件循环管理问题。
run_polling
不是协程函数,不应在协程函数中使用。此外,没有方法 Application.idle()
- 这看起来像 updater.idle()
版本 13 及更早版本中使用的 python-telegram-bot
代码。
使您的
main
函数成为标准的非协程函数,并在不使用 asyncio.run
的情况下调用它。删除 await
前面的 application.run_polling
。这应该可以解决问题。
我强烈建议阅读PTB团队提供的官方资源以熟悉该库。
免责声明:我目前是
python-telegram-bot
的维护者。