你已经 source .venv/bin/activate、pip install -r requirements.txt,在终端里跑得好好的。同一个项目用 Cursor 打开,import 全是红线,Pylance 报 Import "fastapi" could not be resolved,Composer 还热心建议你”pip install fastapi”——明明已经装了。状态栏写着 Python 3.11.7 64-bit,指向 /usr/local/bin/python3 而不是 .venv/bin/python。这是 Python 扩展的解释器发现问题,不是真正的包安装问题,而它会一路传染到 lint、类型检查、agent 修改、运行调试。
常见原因
按 venv 识别失败的发生频率排序。
1. 第一次打开时 Cursor 挑错了解释器
Python 扩展在 workspace 打开时扫描可用解释器,把选择缓存到 .vscode/settings.json。如果你是在 Cursor 第一次打开项目之后才创建的 venv,或者 venv 路径不标准,缓存里会一直指向系统 Python,再也不更新。
如何判断:.vscode/settings.json 里 "python.defaultInterpreterPath" 指向 /usr/local/bin/python 或 /opt/homebrew/bin/python3,而不是 .venv/bin/python。
2. venv 不在工作区根目录下
如果 venv 在 ~/.virtualenvs/myproj(virtualenvwrapper)或者兄弟目录里,扩展的自动扫描就找不到。只有 ./.venv、./venv、./env 会被自动发现。
如何判断:集成终端里 which python 是对的 venv,但状态栏的解释器选择列表里压根没有它。
3. Poetry / PDM / Hatch / uv 管理的 venv
poetry、uv 这类工具会把 venv 放在集中缓存(~/.cache/pypoetry/virtualenvs/...、~/.local/share/uv/python/...)。Cursor 的 Python 扩展只有在启用了对应插件或显式给出路径时才会识别。
如何判断:poetry env info --path 返回的路径,在解释器选择器里看不到。
4. Conda 环境没有在 Cursor 启动器里激活
Conda 环境需要启用 Anaconda 支持,或显式设置 python.condaPath。否则环境出现时 base prefix 是错的,import 也会失败。
如何判断:conda info --envs 显示你的环境存在,但 Cursor 里选中后状态栏仍写 (base)。
5. Cursor 与终端的 shell PATH 不同
Cursor 从启动它的父进程继承 PATH——Finder、Dock、Spotlight。如果你的 venv 激活依赖 .zshrc/.bashrc,那么 GUI 启动 Cursor 时这些 rc 文件根本不会执行。
如何判断:打开集成终端,echo $PATH 少了你在 .zshrc 里写的条目。新开一个 Terminal.app 则一切正常。
6. 多根 workspace,但活跃的那个根没有 Python 配置
multi-root workspace 里每个文件夹都可以有自己的 Python 解释器。状态栏跟着当前编辑器文件所属的根走——在不同根的文件之间切换会悄悄换解释器。
如何判断:同一个 Cursor 窗口里,一个文件 import 没问题,另一个就红线。点击不同文件时状态栏解释器在变。
开始之前
- 先确认 venv 自己是好的:从普通终端
source .venv/bin/activate && python -c "import fastapi"能成功。 - 记下 venv 位置和创建工具(裸
venv、virtualenv、poetry、pdm、uv、conda)。 - 记下 Cursor 状态栏右下角”Python”显示的当前解释器。
- 改之前先保存一份
.vscode/settings.json。
需要收集的信息
- Cursor 集成终端中的
which python与python --version输出。 - 如适用,
poetry env info --path或uv venv --path的输出。 .vscode/settings.json中所有 Python 相关键。- 状态栏解释器的完整路径(不是仅看标签)。
- Pylance “Show language server output” 日志里的
Selected interpreter:行。 - Cursor 是从 Finder、终端
cursor .、还是 Spotlight 启动的。
分步修复
按从快到彻底排序。
第 1 步:通过命令面板显式指定解释器
Cmd+Shift+P -> Python: Select Interpreter -> “Enter interpreter path…”,粘贴绝对路径:
/Users/you/proj/.venv/bin/python
这会把 python.defaultInterpreterPath 写进 .vscode/settings.json 并重启分析器。80% 的情况到这里就解决了。
如果你想用的路径不在列表里,点 “Enter interpreter path…” -> “Find…” 浏览过去。
第 2 步:在 workspace 设置里把解释器固定下来
打开 .vscode/settings.json 锁死:
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true,
"python.analysis.extraPaths": ["${workspaceFolder}/src"]
}
用 ${workspaceFolder} 让路径在不同机器都通用。提交这个文件,队友也能继承同样的选择。
第 3 步:修好 GUI 启动时的 PATH 继承
如果集成终端里 echo $PATH 缺东西,说明 rc 文件没加载。两种办法。
把设置 PATH 的命令从 .zshrc(仅交互式)挪到 .zprofile(登录 shell,也是 Cursor 终端用的):
# ~/.zprofile
export PATH="/opt/homebrew/bin:$HOME/.local/bin:$PATH"
或者从终端启动 Cursor,让它继承正确的环境:
cursor .
两种做法之后都需要把 Cursor 完全退出再启动(不是 Reload Window)。
第 4 步:Poetry / uv / PDM 用户,把 Cursor 指向托管的 venv
先拿路径:
poetry env info --path
# 或
uv venv --path
要么用第 1 步选中这个路径;要么让工具把 venv 创建到项目内:
poetry config virtualenvs.in-project true
poetry env remove --all
poetry install
之后项目根下出现 .venv,自动发现就能工作。
第 5 步:Conda 用户,装 Anaconda Python 扩展并设置 conda 路径
在 Cursor 扩展里装 “Python”(Microsoft),确认 Conda 集成已启用。然后:
{
"python.condaPath": "/opt/homebrew/Caskroom/miniforge/base/condabin/conda",
"python.defaultInterpreterPath": "/opt/homebrew/Caskroom/miniforge/base/envs/myproj/bin/python"
}
通过 Cmd+Shift+P -> Python: Select Interpreter 显式选择 conda 环境。
第 6 步:multi-root workspace,每个根分别固定
multi-root workspace 里,每个文件夹都可以有自己的 .vscode/settings.json。给每个 Python 文件夹都加上:
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
}
这样在文件之间切换就不会再换解释器。
验证
- 打开项目里的
.py文件,状态栏显示Python 3.x.x (.venv)或工具名。 - 输入一个只在 venv 里有的包:
import <pkg>,没有红线。 - 在调试会话里跑
python -c "import sys; print(sys.executable)",输出匹配.venv/bin/python。 - 让 Composer “加一个 fastapi route”,如果包已经在
requirements.txt里,它不应再建议pip install fastapi。
长期预防
- 第一次用 Cursor 打开项目之前,先把 venv 建好。
- 把
python.defaultInterpreterPath写进.vscode/settings.json并提交。 - 用
poetry config virtualenvs.in-project true(或uv venv .venv),让 venv 落在./.venv,能被自动发现。 - PATH 设置写到
.zprofile,不要写在.zshrc,这样 GUI 启动也能继承。 - 提供
make setup/just setup之类的命令,新同事 setup 后 venv 就在标准位置。 - 在
pytest启动时import sys; print(sys.prefix),CI 里 assert 等于.venv。
常见误区
- 选好解释器后又
rm -rf .venv && python -m venv .venv,缓存指向已经不存在的二进制。重新选一次。 - 把
python.defaultInterpreterPath写在 user 设置而不是 workspace 设置:会跨项目泄漏。 - 在集成终端
source .venv/bin/activate然后以为 Pylance 也跟着看见了。Pylance 看的是配置里的解释器,不是终端活跃 venv。 - 只信状态栏标签——它可能写
.venv但实际指向旧路径。一定要用python -c "import sys; print(sys.executable)"验证。 - 从一个 venv 已激活的终端跑
cursor .,行为和从 Finder 启动的不一样。每台机器统一一种启动方式。 - 忘了 conda 环境除了解释器固定,还需要
python.condaPath。
常见问题
Q:Composer 一直建议 pip install 已经装好的包。
agent 读的是 Cursor 选中的解释器。先把解释器修好,建议就不会再来。也可参考Cursor 读错文件。
Q:改了 python.defaultInterpreterPath 但没刷新。
Pylance 会缓存分析器状态。Cmd+Shift+P -> Python: Restart Language Server,或者直接 Reload Window。
Q:我的 venv 在 ~/.virtualenvs/myproj,能继续保留吗?
可以——在 .vscode/settings.json 里固定绝对路径即可。但每个项目用 ./.venv 更简单也更可移植。
Q:终端里测试能过,Cursor 测试浏览器里却挂了。
测试运行器用的是 Cursor 配置里的解释器,不是你终端中的活跃 venv。检查二者是否一致。