设置FLASK_ENV为development时Flask启动提示'No module named flask'的原因
问题描述
我按照Flask 1.1.x的官方步骤完成了虚拟环境安装和基础项目搭建:
- 创建项目目录并执行
python3 -m venv venv创建虚拟环境 - 通过
source venv/bin/activate激活虚拟环境 - 执行
pip install flask完成安装 - 编写了基础的
hello.py脚本:
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!'
设置export FLASK_APP=hello.py后,执行python3 -m flask run可以正常启动服务;但当设置export FLASK_ENV=development后再次执行启动命令,却出现了如下错误:
python3 -m flask run * Serving Flask app "hello.py" (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat /usr/local/opt/python/bin/python3.7: No module named flask
取消FLASK_ENV的设置后,服务又能正常启动。请问这是什么原因导致的?
原因分析
这个问题的核心是Flask调试模式下的进程重启机制没有正确使用虚拟环境的Python解释器。
当你设置FLASK_ENV=development时,Flask会开启调试模式,其中包含自动重启功能——当检测到代码变动时,Flask会用stat重启整个进程。但重启时,它可能没有继承当前虚拟环境的环境变量,转而调用了系统全局的Python解释器(也就是错误信息里的/usr/local/opt/python/bin/python3.7),而全局Python并没有安装Flask,所以就抛出了No module named flask的错误。
为什么正常模式下没问题?因为正常模式下Flask不会重启进程,直接使用当前激活的虚拟环境里的Python解释器来运行服务,所以能找到Flask模块。
解决办法
这里有几个可行的解决方案,你可以根据自己的情况选择:
1. 使用虚拟环境的Python绝对路径启动Flask
找到你虚拟环境中Python的绝对路径(通常是./venv/bin/python),用它来启动Flask,而不是直接用python3:
./venv/bin/python -m flask run
这样即使进程重启,也会明确使用虚拟环境里的Python解释器,不会切换到全局Python。
2. 确认虚拟环境的环境变量配置正确
有时候激活虚拟环境后,PATH变量可能没有被正确修改,导致重启时找不到虚拟环境的Python。你可以手动检查并修正:
# 查看当前PATH,确认虚拟环境的bin目录在最前面 echo $PATH # 如果没有,手动添加 export PATH="./venv/bin:$PATH"
设置完成后再启动服务,Flask重启时就能正确识别虚拟环境的依赖。
3. 关闭自动重启功能(临时方案)
如果你暂时不需要自动重启的便利,可以用--no-reload参数关闭它,避免进程切换的问题:
python3 -m flask run --no-reload
不过这样就失去了调试模式下代码变动自动重启的特性,适合临时排查问题时使用。
4. 重新创建虚拟环境
有时候虚拟环境的激活脚本可能因为权限或路径问题出现异常,你可以尝试重新创建:
deactivate rm -rf venv python3 -m venv venv source venv/bin/activate pip install flask
重新创建后再设置FLASK_ENV=development启动服务,大概率能解决问题。
内容的提问来源于stack exchange,提问作者kristian nissen

