简介:这份资源面向希望在 VS Code 中高效编写 Python 的开发者,尤其适合刚接触该编辑器、需要系统梳理开发环境配置流程的初学者与中级程序员。内容围绕 Python 扩展安装、文件模板设置、解释器与 setting.json 个性化配置、运行调试、代码格式化及自动补全等环节展开,并涉及 Kite 插件对第三方库补全能力的增强,帮助读者搭建顺手的 Python 开发环境。资源包共 3 个文件,以 html 页面、inscode 配置文件和 .gitignore 为主,分别承担说明展示、项目环境标识与版本忽略等用途,压缩包整体约 5KB,体积轻巧便于快速取用。目前已有 133 人学习下载。通过其中的示例与配置思路,读者可对照完成环境搭建、调试设置与补全优化,减少重复摸索,提升日常编码与排错效率。
1. 为什么你的 VS Code 写 Python 总差点意思
很多人装完 VS Code,随手装个 Python 插件,就以为环境搭好了。结果写起代码来,补全慢半拍、调试断点不生效、导入自己写的模块报 ModuleNotFoundError,终端里跑得好好的脚本在调试器里又是另一套解释器。问题不在 VS Code 本身,而在于它默认只是个编辑器,Python 开发需要的解释器管理、语言服务、调试适配、格式化与静态检查,全靠插件和配置一层层拼起来。这套东西配好了,VS Code 就是一个轻量但完整的 Python IDE;配不好,它就是个带高亮的记事本。这篇笔记面向已经会写 Python、但环境总出玄学问题的开发者,从解释器选择一路讲到调试配置和排错,每一步都给可复现的命令和配置,照着做能跑通一个带包结构、能断点、能格式化的最小项目。
2. 解释器、语言服务与插件:先把地基打对
2.1 三个必须分清的组件
VS Code 写 Python 的体验由三层构成,混在一起就会互相甩锅。第一层是 Python 解释器本身,也就是 python.exe 或 python3,它决定你 import 的包从哪来、语法支持到哪个版本。第二层是语言服务,负责补全、跳转、类型提示、错误波浪线,早期靠微软的 Pylance,现在主流也是它,底层是 Pyright 做静态分析。第三层是调试适配器 debugpy,负责把 VS Code 的断点请求翻译成 Python 进程能听懂的命令。
这三层各自独立配置。解释器选错,补全和运行结果对不上;语言服务没启动,补全就是纯文本匹配;debugpy 没装好,断点会变成空心圆。常见做法是先用虚拟环境把解释器隔离,再让 Pylance 指向这个环境,最后确认 debugpy 随 Python 扩展一起装好。
2.2 用 venv 建一个干净的解释器
不要用系统全局 Python 直接开发,包冲突是迟早的事。在项目根目录执行:
# 创建虚拟环境,目录名习惯用 .venv,方便工具识别 python -m venv .venv # 激活:Windows PowerShell .venv\Scripts\Activate.ps1 # 激活:macOS / Linux source .venv/bin/activate # 确认当前解释器路径,后面配置要用 python -c "import sys; print(sys.executable)"逻辑说明:python -m venv会复制一份解释器到.venv目录,并带上独立的 site-packages。激活只是把.venv下的可执行文件放到 PATH 最前面,不改系统环境。最后那条命令打印出的绝对路径,就是接下来要填进 VS Code 的解释器路径。
参数说明:.venv是目录名,用点开头是为了让多数工具默认忽略它;如果你用 conda,对应命令是conda create -n 项目名 python=3.11,激活用conda activate 项目名,路径要用conda info --envs查。
2.3 在 VS Code 里锁定解释器
打开命令面板(Ctrl+Shift+P 或 Cmd+Shift+P),输入Python: Select Interpreter,选中刚才.venv里的那个。选完后项目根目录会生成.vscode/settings.json,内容类似:
{ "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python", "python.analysis.typeCheckingMode": "basic", "python.analysis.autoImportCompletions": true }逻辑说明:python.defaultInterpreterPath告诉扩展默认用哪个解释器,${workspaceFolder}是 VS Code 的变量,指向当前打开的文件夹,这样配置跟着项目走,换机器不用改。typeCheckingMode设成 basic 会在你写错类型时给波浪线,但不至于像 strict 那样满屏红。autoImportCompletions打开后,敲一个没导入的类名,补全列表里会直接带上 import 语句。
参数说明:Windows 下路径是${workspaceFolder}/.venv/Scripts/python.exe,别照抄 Linux 的写法。如果你同时装了多个 Python 版本,defaultInterpreterPath只是默认值,实际生效的仍以命令面板选中的为准,两者不一致时以选中项优先。
2.4 确认 Pylance 和 debugpy 就位
在扩展面板搜 Pylance,确认已安装并启用。debugpy 通常随 Python 扩展自动安装,可以在终端里验证:
# 在激活的虚拟环境里检查 debugpy python -m pip show debugpy # 如果没有,手动装 python -m pip install debugpy逻辑说明:pip show会打印版本和安装位置,能看到说明就绪。debugpy 是调试适配器,VS Code 的 Python 扩展通过它和你的代码进程通信,缺了它断点不会命中。
参数说明:debugpy 版本不必追新,和 Python 扩展兼容即可;如果pip show报 warning 说不在当前环境,多半是虚拟环境没激活,重新激活再试。
3. 从零跑通一个带包结构的最小项目
3.1 目录结构怎么摆
很多人卡在导入自己写的模块上,根因是目录结构不符合 Python 的包规则。一个能跑通、能调试、能测试的最小结构长这样:
demo_project/ ├── .venv/ ├── .vscode/ │ ├── settings.json │ └── launch.json ├── src/ │ └── demo/ │ ├── __init__.py │ ├── calculator.py │ └── main.py ├── tests/ │ └── test_calculator.py └── pyproject.toml逻辑说明:src布局把源码和项目根分开,避免测试时误导入根目录下的同名文件。demo目录下有__init__.py,它才是一个真正的包,from demo.calculator import add这种导入才成立。tests放测试,pyproject.toml声明项目元数据和依赖。
参数说明:__init__.py可以是空文件,它的存在就是告诉 Python 这是个包。如果你不想用 src 布局,把demo直接放根目录也行,但要在配置里把根目录加进python.analysis.extraPaths,否则 Pylance 找不到。
3.2 写两个文件验证导入
src/demo/calculator.py:
# 一个最简计算模块,用来验证导入和调试 def add(a: int, b: int) -> int: result = a + b return result def divide(a: int, b: int) -> float: if b == 0: raise ValueError("除数不能为 0") return a / bsrc/demo/main.py:
# 入口文件,从同包内导入 from demo.calculator import add, divide def main() -> None: print(add(2, 3)) print(divide(10, 2)) if __name__ == "__main__": main()逻辑说明:calculator.py里加了类型标注,Pylance 会据此做检查,传错类型会提示。main.py用绝对导入from demo.calculator import ...,这要求运行时demo包在 sys.path 上。直接python src/demo/main.py会因为找不到demo包而报错,正确做法是从src目录运行,或者把项目按可编辑模式安装。
参数说明:类型标注a: int不影响运行,但能让静态检查和补全更准。if __name__ == "__main__"保证模块被导入时不自动执行 main,这是调试和测试都依赖的惯例。
3.3 让导入生效的两种方式
方式一,从 src 目录运行:
# 进入 src 目录,demo 包就在当前目录下 cd src python -m demo.main方式二,把项目装成可编辑包,在项目根目录执行:
# 需要 pyproject.toml 里配置好项目名和包目录 python -m pip install -e .逻辑说明:python -m demo.main会把当前目录加入 sys.path,所以能找到 demo 包。pip install -e .会在虚拟环境里创建一个指向源码目录的链接,之后在任何位置都能import demo,改代码立即生效,不用重装。
参数说明:-e是 editable 的缩写,装的是开发模式。pyproject.toml里要有[project]段声明 name 和 version,以及[tool.setuptools.packages.find]指向 src,否则-e .找不到包。
3.4 配置 launch.json 让断点命中
在.vscode/launch.json里写:
{ "version": "0.2.0", "configurations": [ { "name": "Python: 调试 demo.main", "type": "debugpy", "request": "launch", "module": "demo.main", "cwd": "${workspaceFolder}/src", "console": "integratedTerminal", "justMyCode": true } ] }逻辑说明:module指定用-m方式启动的模块名,等价于python -m demo.main,这样导入路径和命令行一致。cwd设成 src,保证工作目录正确。console用集成终端,方便看输入输出。justMyCode为 true 时调试器只在你自己的代码里停,不跳进标准库和第三方库。
参数说明:type必须是debugpy,老配置里写python也能用,但新版本推荐 debugpy。request为 launch 表示启动新进程,如果是要附加到已运行进程,改成 attach 并配processId。断点打空心圆通常是justMyCode和路径映射的问题,先确认解释器选对。
4. 格式化、静态检查与测试:把质量门禁接进编辑器
4.1 选 Ruff 还是 Black + Flake8
格式化工具的选择上,Ruff 现在能同时做格式化和 lint,速度比 Black + Flake8 组合快一个量级,配置也集中在一个文件。常见做法是新项目直接用 Ruff,老项目如果已经深度定制了 Flake8 规则,可以保留 Flake8 只把格式化换成 Ruff。安装:
python -m pip install ruff逻辑说明:Ruff 用 Rust 写,单次扫描整个项目通常在百毫秒级,保存时自动格式化几乎无感。它兼容 Black 的格式风格,迁移成本低。
参数说明:如果团队强制 Black 风格,Ruff 的format子命令输出和 Black 基本一致,但极端边界情况仍有差异,混用前先跑一遍对比。
4.2 在 settings.json 里接上保存即格式化
{ "editor.formatOnSave": true, "editor.defaultFormatter": "charliermarsh.ruff", "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.codeActionsOnSave": { "source.fixAll": "explicit", "source.organizeImports": "explicit" } }, "ruff.lineLength": 100 }逻辑说明:formatOnSave打开后每次保存自动格式化。[python]段专门针对 Python 文件指定格式化器和保存时的代码动作。source.fixAll让 Ruff 自动修可修的 lint 问题,source.organizeImports自动整理 import 顺序。ruff.lineLength设成 100,比默认 88 宽松,适合屏幕宽的开发者。
参数说明:"explicit"表示只在手动保存时触发,避免自动保存频繁格式化打断输入。如果你用 Black,把格式化器换成ms-python.black-formatter,lineLength 在 Black 扩展的设置里配。
4.3 用 pytest 做测试并接进编辑器
装 pytest:
python -m pip install pytest写tests/test_calculator.py:
# 测试文件,验证 calculator 的两个函数 import pytest from demo.calculator import add, divide def test_add(): assert add(2, 3) == 5 def test_divide_normal(): assert divide(10, 2) == 5.0 def test_divide_by_zero(): # 验证异常分支 with pytest.raises(ValueError): divide(1, 0)逻辑说明:pytest 会自动发现test_开头的文件和函数。pytest.raises用来断言抛出了指定异常,覆盖除零分支。测试要能 import 到 demo 包,所以要么从 src 目录跑,要么项目已pip install -e .。
参数说明:在 VS Code 里按 Ctrl+Shift+P 输入Python: Configure Tests,选 pytest,再选 tests 目录,之后测试文件里每个函数上方会出现运行按钮,点一下就能单跑。失败时输出面板会给出断言差异。
4.4 用 tasks.json 固化常用命令
{ "version": "2.0.0", "tasks": [ { "label": "ruff check", "type": "shell", "command": "${workspaceFolder}/.venv/bin/ruff check src tests", "problemMatcher": [] }, { "label": "pytest", "type": "shell", "command": "${workspaceFolder}/.venv/bin/pytest tests -v", "problemMatcher": [] } ] }逻辑说明:把 lint 和测试命令固化成任务,Ctrl+Shift+B 就能跑,不用每次敲长命令。problemMatcher留空表示不解析输出到问题面板,需要的话可以配 Ruff 和 pytest 的 matcher。
参数说明:Windows 下命令路径改成${workspaceFolder}/.venv/Scripts/ruff.exe。-v让 pytest 输出每个用例名,排查失败时更清楚。
5. 避坑与排查:那些让断点变空心圆的瞬间
5.1 断点空心圆,程序直接跑完
现象:断点显示为空心圆,调试启动后代码直接执行完,没停。原因通常是解释器选错,调试器用的 Python 和你以为的不是同一个,或者justMyCode把当前文件判定为非用户代码。解决:命令面板重新选解释器,确认路径指向.venv;检查 launch.json 里justMyCode是否为 true,如果代码在 src 布局下但 cwd 没设对,调试器可能把文件当外部代码。把cwd设成${workspaceFolder}/src再试。
5.2 补全列表里没有自己写的模块
现象:from demo.敲下去,补全列表空,但运行没问题。原因是 Pylance 的搜索路径没包含 src。解决:在 settings.json 里加"python.analysis.extraPaths": ["${workspaceFolder}/src"],或者把项目pip install -e .装进环境。前者改配置即可,后者更接近真实运行环境,推荐后者。
5.3 保存时格式化把 import 顺序改乱
现象:保存后 import 被重排,和团队约定不一致。原因是 Ruff 的organizeImports默认按 isort 规则排,可能和你们的手动顺序不同。解决:在 pyproject.toml 里配[tool.ruff.lint.isort]的known-first-party等参数,或者关掉source.organizeImports,只保留格式化。团队统一规则比个人偏好重要。
5.4 调试时改了代码,断点位置对不上
现象:调试中改了文件,重新跑发现断点停在旧行号。原因是调试器加载的是启动时的字节码,改文件不会热重载。解决:改完代码停止调试再重新启动。如果频繁改,用--looponfail之类的工具或 pytest 的 watch 模式,但调试器本身不做热重载,这是设计如此。
5.5 虚拟环境激活了,VS Code 终端里还是全局 Python
现象:终端里which python指向全局,但明明激活了.venv。原因是 VS Code 的集成终端在启动时可能没继承激活状态,或者 settings.json 里python.terminal.activateEnvironment被关了。解决:确认该设置为 true,重启终端;或者直接在 launch.json 里用python字段指定解释器绝对路径,绕开激活步骤。
6. 进阶:把配置变成可复用的开发模板
配好一个项目后,最省事的做法是把.vscode和pyproject.toml抽成模板,新项目直接复制。我一般会维护一个最小模板仓库,里面 settings.json 只留解释器路径、格式化、extraPaths 三项,launch.json 留一个 module 启动配置,pyproject.toml 里固定 Ruff 和 pytest 的配置。新项目git clone模板,改个包名就能开工。
验证模板是否可用,有个具体技巧:删掉.venv,重新python -m venv .venv并激活,然后只跑三条命令——pip install -e .、ruff check src tests、pytest tests -v。三条都过,说明配置不依赖任何本机残留状态。这个习惯帮我省过很多次「在我机器上能跑」的后悔药。
再进一步,可以把这套配置和 CI 对齐。本地 Ruff 的规则集、pytest 的路径,和 CI 里跑的命令保持一致,避免本地过、流水线挂。具体做法是在 pyproject.toml 里集中配[tool.ruff]和[tool.pytest.ini_options],CI 直接调ruff check和pytest,不额外传参。这样本地和远端用的是同一份规则,差异只可能出在 Python 版本上,而版本在 pyproject.toml 的requires-python里锁死。
最后说个我踩过的坑:有段时间我图省事,把.venv提交进了仓库,结果换机器后解释器路径全错,Pylance 报一堆找不到模块。后来在.gitignore里加上.venv/,模板里只留配置不留环境,问题消失。环境是本地生成的,配置才是要复用的资产,这个边界分清,VS Code 写 Python 才算真正顺手。希望帮到你。
本文还有配套的精品资源,点击获取