在PythonAnywhere运行WSGI应用时遇错误求助
解决PythonAnywhere上运行aiohttp应用时的
TypeError: '_UnixSelectorEventLoop' object is not callable错误 问题分析
你遇到的错误核心是事件循环使用逻辑错误,结合代码来看有两个关键问题:
loop.run_in_executor的用法不符合预期:该方法用于在事件循环中执行同步阻塞函数,但如果run_bot或run_server是异步函数,直接传入会导致调用逻辑混乱;- PythonAnywhere的WSGI环境本身会管理进程/线程,手动创建事件循环并搭配
ProcessPoolExecutor会引发兼容性问题,容易导致事件循环对象被错误调用。
修复步骤
1. 调整异步任务的启动方式
如果run_bot和run_server是异步函数,不需要用ProcessPoolExecutor,直接在事件循环中创建异步任务即可:
import asyncio from aiohttp import web async def run_bot(): # 你的机器人业务逻辑 pass async def run_server(): app = web.Application() # 配置web路由示例 async def hello(request): return web.Response(text="Hello from aiohttp") app.add_routes([web.get('/', hello)]) runner = web.AppRunner(app) await runner.setup() # PythonAnywhere要求端口为8000 site = web.TCPSite(runner, '0.0.0.0', 8000) await site.start() # 保持服务器持续运行 await asyncio.Event().wait() async def main(): # 同时启动两个异步任务 task_bot = asyncio.create_task(run_bot()) task_server = asyncio.create_task(run_server()) # 等待所有任务完成 await asyncio.gather(task_bot, task_server) if __name__ == '__main__': asyncio.run(main())
2. 适配PythonAnywhere的WSGI环境
PythonAnywhere默认使用WSGI容器,而aiohttp是ASGI框架,需要用aiohttp-wsgi包装应用以适配:
- 先安装依赖:
pip install aiohttp-wsgi - 修改
main.py添加WSGI适配逻辑:
import asyncio from aiohttp import web from aiohttp_wsgi import WSGIHandler async def run_bot(): # 你的机器人业务逻辑 pass def create_web_app(): app = web.Application() # 配置web路由 async def hello(request): return web.Response(text="Hello from aiohttp") app.add_routes([web.get('/', hello)]) return app # 创建WSGI处理程序 wsgi_handler = WSGIHandler(create_web_app()) # 启动异步任务和WSGI服务 async def main(): task_bot = asyncio.create_task(run_bot()) # 保持服务运行 await asyncio.Event().wait() await task_bot # PythonAnywhere的WSGI入口 application = wsgi_handler.application
3. 避免手动管理事件循环和进程池
- 不要手动调用
asyncio.new_event_loop(),Python 3.7+推荐用asyncio.run()自动管理事件循环; - 若存在同步阻塞任务(如IO密集型操作),优先用线程池而非进程池配合
run_in_executor:
# 同步阻塞任务处理示例 async def handle_blocking_operation(): loop = asyncio.get_event_loop() # 默认使用线程池 result = await loop.run_in_executor(None, your_sync_blocking_function) return result
内容的提问来源于stack exchange,提问作者ngzs
相关产品推荐
相关产品推荐

