Tornado框架Python Web项目启动报NotImplementedError的解决方法
解决Tornado调用
app.listen()时的NotImplementedError问题 这个错误我之前在Windows上用Python 3.8+跑Tornado项目时也遇到过,核心原因是Python 3.8起,Windows平台的asyncio默认事件循环换成了ProactorEventLoop,而这个循环不支持Tornado底层依赖的add_reader操作,导致绑定端口时抛出异常。
下面给你两个靠谱的修复方案,任选其一即可:
方案一:强制设置asyncio使用Selector事件循环
在你的主程序入口(if __name__ == "__main__":代码块的最开始)添加以下代码,强制指定使用兼容Tornado的事件循环:
import asyncio # 针对Windows平台设置Selector事件循环 asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
修改后的主程序部分示例:
if __name__ == "__main__": # 先设置事件循环策略,解决Windows下的兼容性问题 import asyncio asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) # Define settings/options for the web app tornado.options.define("port", default=6000) tornado.options.define("debug", default=True) tornado.options.parse_command_line() options = tornado.options.options app = make_app(options) app.listen(options.port) logging.info("Starting listing service. PORT: {}, DEBUG: {}".format(options.port, options.debug)) tornado.ioloop.IOLoop.instance().start()
方案二:直接使用Tornado的SelectorIOLoop
另一种方式是直接让Tornado使用Selector类型的IOLoop,替换默认的实现:
from tornado.ioloop import SelectorIOLoop # 配置全局IOLoop为SelectorIOLoop SelectorIOLoop.configure()
把这段代码放在启动事件循环之前,比如:
# ... 前面的代码不变 ... app.listen(options.port) logging.info("Starting listing service. PORT: {}, DEBUG: {}".format(options.port, options.debug)) # 配置使用SelectorIOLoop from tornado.ioloop import SelectorIOLoop SelectorIOLoop.configure() tornado.ioloop.IOLoop.instance().start()
补充说明
- 这个问题只在**Windows + Python 3.8+**的环境下出现,Linux/macOS平台默认的事件循环是
SelectorEventLoop,不会有这个问题。 - 两种方案本质都是让Tornado运行在兼容的事件循环上,任选其一就能解决
NotImplementedError。
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

