Python开发环境与工具链:VSCode、UV、Ruff

Python开发环境与工具链:VSCode、UV、Ruff

VSCode SetUp

Extensions list

  • Python
  • Pylance
  • Ruff
  • Python Debugger
  • Python postfix completion

Formatter & Linter

后文提到的 Ruff 不仅可以在命令行中使用,还可以集成到 VS Code 中,以便在保存文件时自动格式化和检查代码。或者也可以用微软维护的 Black Formatter 的插件

VS Code 配置示例: 在 .vscode/settings.json 中添加以下配置,使得代码在保存时自动格式化和修复

JSON
"editor.formatOnPaste": true,"editor.formatOnSave": true,"editor.formatOnType": true,"[python]": {  "editor.codeActionsOnSave": {    "source.fixAll.ruff": "always", // fix all    "source.organizeImports.ruff": "always", // sort imports  },  "editor.defaultFormatter": "charliermarsh.ruff"},

LSP

推荐 Pylance 作为 LSP,个人开发过程中的配置 👇

JSON
"python.languageServer": "Pylance","python.analysis.cacheLSPData": true,"python.analysis.typeEvaluation.enableReachabilityAnalysis": true,// inlay hints releated"editor.inlayHints.enabled": "offUnlessPressed","python.analysis.inlayHints.callArgumentNames": "all","python.analysis.inlayHints.functionReturnTypes": true,"python.analysis.inlayHints.pytestParameters": true,"python.analysis.inlayHints.variableTypes": true,"python.analysis.typeEvaluation.deprecateTypingAliases": true,"python.analysis.autoFormatStrings": true,"python.analysis.autoImportCompletions": true,"python.analysis.completeFunctionParens": true, // 类型检查设置为 strict,大型项目中,推荐使用,保证软件Robustness"python.analysis.typeCheckingMode": "strict",// 启用同步服务器,暂时不稳定(2024年10月),默认是关闭的,不推荐使用"python.analysis.enableSyncServer": false,"python.analysis.typeEvaluation.enableExperimentalFeatures": true,"python.terminal.activateEnvInCurrentTerminal": true,"python.terminal.shellIntegration.enabled": true,"python.analysis.fixAll": [  "source.unusedImports",  "source.convertImportFormat"],"python.analysis.nodeExecutable": "/usr/sbin/node",

Package & Project Management

python 管理环境的工具有点过多了 😵‍💫

  • conda create --name <venv_name>
  • python -m venv <venv_name>
  • poetry

这里选择了UV An extremely fast Python package and project manager, written in Rust.

使用过程中就感觉到快 😎👍

benchmark

Installation

SHELL
# On macOS and Linux.$ curl -LsSf https://astral.sh/uv/install.sh | sh# On Windows.$ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"# With pip.$ pip install uv

使用方法可以参见 uv 官方文档
下面是个人比较常用的命令

Virtual Environment

SHELL
# 创建虚拟环境$ uv venv myenvUsing CPython 3.12.7 interpreter at: /usr/sbin/pythonCreating virtual environment at: myenv# 激活虚拟环境$ overlay use myenv/bin/activate.nu# 退出虚拟环境$ deactivate# 切换项目使用的 Python 版本$ uv python pin 3.12Updated `.python-version` from `3.13`  `3.12`$ uv syncUsing CPython 3.12.7 interpreter at: /usr/sbin/pythonRemoved virtual environment at: .venvCreating virtual environment at: .venvResolved 44 packages in 1msAudited in 0.00ms# 列出可用的Python版本,包括已下载和可供下载的$ uv python list# 下载指定版本的python$ uv python install 3.12Searching for Python versions matching: Python 3.13Installed Python 3.13.0 in 7.77s + cpython-3.13.0-linux-x86_64-gnu

Dependency

uv 也实现了部分 pip 的功能,使用 uv pip install -r requirements.txt 或 uv pip install -r pyproject.toml --extra dev

导出依赖
将 pyproject.toml 文件导出为 requirements.txt 格式:uv pip compile ./pyproject.toml -o ./requirements.txt

SHELL
# 添加依赖uv add ruffuv pip install ruff# 更新依赖uv add ruff==0.7.2# 卸载依赖uv remove ruff

Formatter&Linter —— Ruff

Ruff An extremely fast Python linter and code formatter, written in Rust.

  • Linter: A Linter is a tool that analyzes your code and reports on potential issues.
  • Formatter: A Formatter is a tool that automatically formats your code.

ruff 可以在 pyproject.toml 中配置,也可以在 .ruff.toml 中配置
具体参数可以参考 Ruff Configuration

此外,在 Git 中可以设置 Pre-push hook,在每次代码推送前自动运行 Ruff 检查。以下是一个示例脚本,将其保存为 ./.git/hooks/pre-push。下面代码比较暴力,直接检查当前目录下 Python File 的格式是否正确,可以自己改一下,只检查已 commit 的代码

SHELL
cat ./.git/hooks/pre-push#!/bin/sh# 运行 ruff 检查uv run ruff check .# 检查 ruff 的退出状态if [ $? -ne 0 ]; then    echo "Ruff check failed. Please fix the issues before push."    exit 1fiecho "All checks passed."

MISC

__pycache__

在 Python 开发中,项目会生成一些临时文件和缓存文件,比如 __pycache__ 目录。不需要时,可以用下面的命令可以递归删除这些缓存文件夹

  • python3 -Bc "import pathlib; [p.rmdir() for p in pathlib.Path('.').rglob('__pycache__')]"
  • python3 -Bc "import pathlib; [p.rmdir() for p in pathlib.Path('.').rglob('.pytest_cache')]"
  • find . -type d -name __pycache__ -exec rm -r {} \+
  • find ./ -type f -name '*.pyc' -delete -print && find ./ -type d -name "pycache" -delete -print

StackOverFlow: Python3 project remove __pycache__ folders and .pyc files

pyproject.toml

为了规范化 Python 项目的构建系统,Python 社区提出了 PEP 518,提案提出使用pyproject.toml方法指定 Python 项目的构建系统及其依赖关系,避免多个不同工具之间的配置文件不一致问题。详见Writing your pyproject.toml

  • The [build-system] table is strongly recommended. It allows you to declare which build backend you use and which other dependencies are needed to build your project.
  • The [project] table is the format that most build backends use to specify your project’s basic metadata, such as the dependencies, your name, etc.
  • The [tool] table has tool-specific subtables, e.g., [tool.hatch], [tool.black], [tool.mypy]. We only touch upon this table here because its contents are defined by each tool. Consult the particular tool’s documentation to know what it can contain.

[build-system]暂不涉及,其主要负责 python 打包和发布相关的配置
[project] 主要负责项目元数据,如项目名称、版本、依赖等
[tool] 可以集中配置各种工具,如 ruffblackpytest等,统一在pyproject.toml里,保持根目录的整洁

TOML
[project]name = "vnet"version = "0.1.0"description = "virtual network"readme = "README.md"requires-python = ">=3.10"dependencies = [][project.optional-dependencies]doc = ["mkdocs-material", "mkdocs-mermaid2-plugin"]dev = ["pytest>=8.3.3", "ruff==0.7.2", "pytest-cov"][tool.ruff]line-length = 100target-version = "py312"respect-gitignore = trueindent-width = 4[tool.ruff.format]quote-style = "double"indent-style = "tab"docstring-code-format = true[tool.ruff.lint]ignore = ["E402"][tool.pytest.ini_options]# 设置syspath目录pythonpath = "/home/efterklang/workspace/vnet"# 添加命令行选项addopts = "-vs"# 指定测试路径testpaths = ["./test"]# 指定测试文件和命名规则python_files = ["test_*.py"]python_classes = "Test*"python_functions = "test_*"# 命令行日志输出设置log_cli = truelog_cli_format = "%(asctime)s [%(levelname)s] %(message)s"log_cli_date_format = "%m.%d %H:%M:%S"

@dataclass

在 Python 中,定义一个类常常需要编写重复的代码,如构造函数(__init__)、比较函数(__eq__)、字符串表示(__repr__)等。为了解决这一问题,Python 3.7 引入了 @dataclass 装饰器,帮助开发者自动生成这些函数。@dataclass 的出现简化了类的定义,尤其是那些主要用于存储数据的类,减少样板代码(boilerplate),使得代码更加简洁和易读。

Java 中与之类似的是 record,JDK14 引入的。public record Person(String name, int age) {}

Lombok提供了@Data注解,也可以自动生成 getter、setter、toString 等方法

官方文档 👉dataclasses — Data Classes

  • frozen=True ,可以让类的实例变为不可变对象,类似于 namedtuple
PYTHON
@dataclass(frozen=True)class Point:    x: int    y: intp = Point(10, 20)# p.x = 30  # 这会抛出错误,因为 Point 是不可变的
  • 通过 field() 函数,可以为类中的字段设置元数据,如是否初始化、默认工厂等。
PYTHON
from dataclasses import dataclass, field@dataclassclass User:    username: str    password: str = field(repr=False)  #  __repr__ 中隐藏该字段user = User(username="alice", password="secret")print(user)  # 输出:User(username='alice')
  • asdictastuple :可以将数据类转换为字典或元组。有时候需要将数据类转换为其他格式,比如 JSON;序列化时可以使用asdict减少编码工作,此外也可以选择Pydantic,Marshmallow等库

Python开发环境与工具链:VSCode、UV、Ruff

https://vluv.space/Python开发环境与工具链/

作者

GnixAij

发布于

2024-11-06

更新于

2025-08-12

许可协议

评论