使用Telethon与Quart+asyncio遇循环问题:Future关联不同事件循环
解决Telethon + Quart 使用
asyncio.run()启动时的循环冲突问题 核心原因
asyncio.run()会创建一个全新的独立事件循环,而Quart框架内部会自动初始化并绑定自己的事件循环,Telethon的client.start()如果在不同循环上下文执行,就会触发"Future attached to a different loop"的错误。
替代方案(兼容Python3.7+,无弃用警告)
方案1:让Telethon和Quart共享同一个事件循环
在main()函数中,先获取当前由asyncio.run创建的循环,确保Quart和Telethon都使用这个循环:
import asyncio from quart import Quart from telethon import TelegramClient app = Quart(__name__) client = TelegramClient('session_name', API_ID, API_HASH) async def main(): # 获取当前运行中的事件循环 loop = asyncio.get_running_loop() # 绑定Quart到该循环 app.loop = loop # 启动Telethon客户端 await client.start() # 使用Quart的run_task方法启动服务,避免创建新循环 await app.run_task(host='0.0.0.0', port=5000) if __name__ == '__main__': asyncio.run(main())
关键说明:
asyncio.get_running_loop()是Python3.7+推荐的获取当前运行中循环的方式,不会触发弃用警告- Quart的
run_task()方法会在当前循环内启动服务,而非创建新循环,彻底避免循环冲突
方案2:显式创建并管理循环生命周期
如果需要更精细的控制,可以手动创建循环,确保所有组件绑定同一实例:
import asyncio from quart import Quart from telethon import TelegramClient app = Quart(__name__) client = TelegramClient('session_name', API_ID, API_HASH) async def main(): await client.start() await app.run_task(host='0.0.0.0', port=5000) if __name__ == '__main__': # 显式创建循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(main()) finally: loop.close()
该方式和asyncio.run()的内部逻辑一致,但手动管理循环生命周期,确保Telethon与Quart共享同一循环。
额外注意事项
- 所有异步初始化逻辑(包括Telethon客户端启动、Quart扩展加载)都要放在
main()函数内部,确保在同一个循环上下文执行 - 不要在全局作用域提前执行异步操作,避免循环绑定错误
内容的提问来源于stack exchange,提问作者Qliver
相关产品推荐
相关产品推荐

