编程 Ruff 深度拆解:当 Python 决定「用 Rust 重建整个工具链」——从 Flake8 到 Black 到 mypy,一个 Astral 生态如何用 100 倍速度重新定义代码质量的终极形态

2026-08-05 07:15:24 +0800 CST views 7

Ruff 深度拆解:当 Python 决定「用 Rust 重建整个工具链」——从 Flake8 到 Black 到 mypy,一个 Astral 生态如何用 100 倍速度重新定义代码质量的终极形态

引言:Python 开发者的「工具链噩梦」

如果你是一个 Python 开发者,你一定经历过这样的场景:

刚写完一个函数,按下保存,IDE 里弹出三个不同颜色的波浪线——红色的是 mypy 报的类型错误,黄色的是 Flake8 报的风格问题,蓝色的是 isort 报的 import 排序问题。你打开终端,依次运行:

isort .
black .
flake8 .
mypy .

四个工具,四个配置文件(.flake8pyproject.toml 里的 [tool.black][tool.isort]mypy.ini),四套互不兼容的规则体系。项目一大,跑一次完整检查要等几十秒甚至几分钟。CI 流水线里,代码质量检查往往是耗时最长的环节。

这不是个别现象,这是 Python 生态二十多年来的「历史包袱」。Flake8 诞生于 2010 年,Black 发布于 2018 年,isort 更早——它们都是各自时代的最佳实践,但从未被设计成一个统一的系统。

2022 年,一家名叫 Astral 的公司决定终结这一切。他们用 Rust 重写了 Python 的整个开发工具链,创造了三个颠覆性的工具:

  • uv:Python 包管理器,替代 pip/pip-tools/venv
  • Ruff:Python 代码检查器和格式化器,替代 Flake8 + Black + isort + 100 多个插件
  • ty:Python 类型检查器,替代 mypy/pyright

这三个工具全部用 Rust 编写,性能提升 10-100 倍,配置统一到一个 pyproject.toml 文件里。截至 2026 年 8 月,Ruff 在 GitHub 上已获得超过 47,000 Star,uv 超过 55,000 Star,成为 Python 生态增长最快的项目。

本文将深入拆解 Astral 工具链的架构设计、核心实现和迁移路径,告诉你为什么「用 Rust 重建 Python 工具链」不是一个噱头,而是一场正在发生的范式革命。

第一章:Python 工具链的历史债务

1.1 碎片化的工具生态

Python 的代码质量工具生态可以用「百花齐放」来形容,但这个词在这里是贬义的。

代码检查(Linting):Flake8 是事实标准,但它本身只是一个薄壳——真正的检查能力来自 100 多个插件(flake8-bugbearflake8-comprehensionsflake8-simplify……)。每个插件有自己的版本节奏,规则之间偶尔还会冲突。

代码格式化:Black 在 2018 年横空出世,用「无妥协」的哲学统一了 Python 格式化。但在 Black 之前,YAPF、autopep8、blue 等工具已经存在了很久。至今仍有人坚持用 YAPF。

Import 排序:isort 是标准选择,但它和 Black 之间曾有过著名的「格式冲突」——isort 默认的多行模式和 Black 的格式化结果不兼容,社区花了好几年才通过 isort --profile black 解决这个问题。

类型检查:mypy 是 Python 官方推荐的类型检查器,但 pyright(微软出品)在性能和准确性上经常超越 mypy。两者对 PEP 484 的实现程度不同,对第三方库的类型 stub 支持也不同。

复杂度分析:radon、xenon 等工具独立于上述体系之外。

每个工具都有自己的配置文件格式、自己的命令行接口、自己的插件系统。一个中等规模的 Python 项目,光是配置这些工具就要花半天时间。更糟糕的是,当团队成员的本地环境和 CI 环境的工具版本不一致时,「本地通过但 CI 失败」的幽灵 bug 就会出现。

1.2 性能瓶颈

Python 工具链的另一个致命问题是性能。

Flake8 用 Python 写成。在一个拥有 50 万行代码的大型项目上,运行一次完整的 Flake8 检查可能需要 30 秒到 2 分钟。Black 的格式化速度稍快,但在大型文件上也需要几秒。

这意味着什么?当你在 IDE 里保存文件时,你不可能「即时」看到所有检查结果。你必须等待。在 CI 流水线里,代码质量检查往往是串行执行的最耗时环节:

# 典型的 CI 配置
- run: isort --check-only .
- run: black --check .
- run: flake8 .
- run: mypy .

四个工具串行执行,每个都要重新扫描整个代码库。总耗时可能是 3-5 分钟。

1.3 Astral 的野心

Astral 公司由 Charlie Marsh(Ruff 的创始人)于 2022 年创立。他们的核心洞察是:Python 的工具链问题不是功能问题,而是性能问题和集成问题

如果一个工具能比现有工具快 100 倍,并且能在一个配置文件里统一所有规则,那么「工具碎片化」的问题就从根本上解决了。

Astral 选择 Rust 作为实现语言,原因很直接:Rust 提供了接近 C 的性能,同时有优秀的内存安全保证和现代的包管理生态。用 Rust 写的工具可以编译成单个二进制文件,无需 Python 运行时,安装和分发都极其简单。

第二章:Ruff 架构深度解析

2.1 核心架构

Ruff 的架构可以用一句话概括:一个 Rust 实现的 Python AST 解析器 + 一个可扩展的规则引擎 + 一个确定性格式化器

┌─────────────────────────────────────────────┐
│                  Ruff CLI                    │
├─────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────────────┐ │
│  │  Python AST   │  │   Rule Engine        │ │
│  │  Parser       │──│  (800+ rules)        │ │
│  │  (Rust)       │  │  + Fix Generator     │ │
│  └──────────────┘  └──────────────────────┘ │
│           │                    │              │
│  ┌──────────────┐  ┌──────────────────────┐ │
│  │  Formatter    │  │   Import Sorter      │ │
│  │  (Black-      │  │   (isort-            │ │
│  │   compatible) │  │    compatible)       │ │
│  └──────────────┘  └──────────────────────┘ │
└─────────────────────────────────────────────┘

Python AST 解析器:Ruff 内置了一个用 Rust 编写的 Python 语法解析器,可以直接将 Python 源代码解析为抽象语法树(AST),无需调用 Python 解释器。这是性能提升的关键——传统的 Python lint 工具需要启动 Python 进程,通过 ast 模块解析代码,这个过程本身就有很大的开销。

规则引擎:Ruff 实现了 800 多条检查规则,覆盖了 Flake8 的绝大多数插件功能。每条规则都是一个独立的 Rust 模块,通过 trait 系统注册到规则引擎中。规则引擎遍历 AST,对每个节点应用所有匹配的规则,生成诊断信息。

格式化器:Ruff 的格式化器旨在产出与 Black 完全一致的结果。它不是「类似 Black」,而是「Black 兼容」——你可以用 Ruff 格式化现有 Black 项目,diff 结果应该是空的。

Import 排序器:Ruff 内置了 isort 兼容的 import 排序功能,支持 isort 的所有配置选项。

2.2 性能优化的秘密

Ruff 为什么能比 Flake8 快 100 倍?核心原因有三个:

1. 零 Python 进程开销

Flake8 每次运行都需要启动一个 Python 解释器,加载插件,然后解析代码。这个启动过程在大型项目上可能就需要几秒。Ruff 是一个原生二进制文件,启动时间在毫秒级别。

2. 增量分析

Ruff 支持增量分析——当文件没有变化时,可以直接复用上次的分析结果。在 IDE 集成场景下,这意味着「保存即检查」成为可能。

3. 并行处理

Ruff 的规则引擎可以并行处理多个文件。在多核 CPU 上,大型项目的检查时间可以进一步缩短。

让我们看一个实际的性能对比:

# 在 CPython 代码库(约 50 万行)上的对比
$ time flake8 .
real    0m47.321s

$ time ruff check .
real    0m0.847s

# 提速 55 倍
# 格式化对比
$ time black --check .
real    0m12.456s

$ time ruff format --check .
real    0m0.234s

# 提速 53 倍

2.3 规则设计哲学

Ruff 的规则设计遵循两个核心原则:

原则一:默认安全

Ruff 的默认规则集只包含「几乎不会误报」的检查。你不需要花时间配置「忽略这个误报」。这和 Flake8 形成了鲜明对比——Flake8 的很多插件会产生大量误报,迫使开发者在配置文件里维护一个长长的 ignore 列表。

原则二:可自动修复

Ruff 的很多规则都支持自动修复(--fix)。这意味着你不需要手动修改代码来修复风格问题——Ruff 可以帮你做。

# 一键修复所有可修复的问题
$ ruff check --fix .

# 格式化整个项目
$ ruff format .

第三章:uv — 包管理的革命

3.1 为什么需要另一个包管理器?

Python 的包管理工具历史是一部混乱史:

  • distutils(2000年):Python 标准库自带,功能极其有限
  • setuptools(2004年):distutils 的增强版,成为事实标准
  • pip(2008年):setuptools 的前端,成为「标准」包安装器
  • virtualenv(2007年):虚拟环境工具,后来被 python -m venv 取代
  • pip-tools(2016年):依赖锁定工具
  • Poetry(2018年):试图统一包管理和依赖锁定
  • PDM(2021年):PEP 621 的实现
  • Hatch(2022年):PyPA 官方推荐的项目管理工具

每个工具都有自己的锁文件格式、自己的配置方式、自己的虚拟环境管理策略。Poetry 的 poetry.lock、PDM 的 pdm.lock、Pipenv 的 Pipfile.lock——三个本质上做同一件事的工具,用了三种不兼容的格式。

3.2 uv 的设计哲学

uv 的设计哲学可以用一句话概括:用 Rust 的速度,做 pip 的事情,但做得更好

uv 的核心特性:

  1. 速度:比 pip 快 10-100 倍
  2. 兼容性:完全兼容 pip 的命令行接口和 requirements.txt 格式
  3. 虚拟环境:内置虚拟环境管理,无需额外工具
  4. 依赖解析:使用 PubGrub 算法(与 Cargo 相同),解析速度极快
  5. 缓存:全局缓存 + 硬链接,避免重复下载

3.3 实战:从 pip 迁移到 uv

安装 uv

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# 或通过 pip
pip install uv

基本用法对比

# pip 方式
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install pytest black flake8 --dev

# uv 方式(一条命令搞定)
uv venv
uv pip install -r requirements.txt
uv pip install pytest black flake8 --dev

依赖锁定

# 生成锁文件(类似 pip-compile)
uv pip compile requirements.in -o requirements.txt

# 从锁文件安装(确保可复现)
uv pip sync requirements.txt

项目管理

# 初始化新项目
uv init my-project
cd my-project

# 添加依赖
uv add fastapi uvicorn

# 添加开发依赖
uv add --dev pytest ruff

# 运行脚本
uv run python main.py

# 运行工具
uv run ruff check .

3.4 uv 的架构

uv 的核心架构分为几层:

┌─────────────────────────────────────┐
│            uv CLI                    │
├─────────────────────────────────────┤
│  ┌─────────────┐  ┌──────────────┐ │
│  │  Resolver     │  │  Installer   │ │
│  │  (PubGrub)    │  │  (Hardlink)  │ │
│  └─────────────┘  └──────────────┘ │
│  ┌─────────────┐  ┌──────────────┐ │
│  │  Cache        │  │  Download    │ │
│  │  Manager      │  │  Manager     │ │
│  └─────────────┘  └──────────────┘ │
│  ┌─────────────────────────────────┐│
│  │  PyPI Client (async, parallel)  ││
│  └─────────────────────────────────┘│
└─────────────────────────────────────┘

依赖解析器:uv 使用 PubGrub 算法进行依赖解析,这是目前最先进的版本求解算法之一(Rust 的 Cargo 也使用相同的算法)。PubGrub 的核心思想是「冲突驱动学习」——当解析过程中遇到冲突时,算法会学习到一个新的约束,并回溯到更早的状态重新尝试。

缓存系统:uv 实现了一个智能缓存系统。下载的包会存储在全局缓存目录中,后续安装时通过硬链接(hardlink)直接引用缓存文件,避免重复下载和解压。这在 CI 场景下特别有用——第一次运行可能需要几分钟下载依赖,后续运行只需要几秒钟。

并行下载:uv 使用 async Rust(tokio)实现并行下载。当安装一个有 100 个依赖的项目时,uv 可以同时下载所有依赖,而不是像 pip 那样串行下载。

第四章:ty — 类型检查的新范式

4.1 mypy 的困境

mypy 是 Python 类型检查的事实标准,但它有几个长期存在的问题:

  1. 性能慢:在大型项目上,mypy 可能需要 30 秒甚至更长时间
  2. 增量检查不可靠:mypy 的增量检查模式经常漏掉错误
  3. 第三方库类型支持不完整:很多第三方库的类型 stub 缺失或过时
  4. 配置复杂mypy.ini 的配置项多达 100 多个

4.2 ty 的定位

ty 是 Astral 推出的 Python 类型检查器,目标是成为 mypy/pyright 的 Rust 替代品。

核心特性

  1. 极致性能:比 mypy 快 10-100 倍
  2. Python 3.14 兼容:第一时间支持最新的 Python 特性
  3. LSP 支持:内置语言服务器协议支持,可直接集成到 IDE
  4. 渐进式类型检查:支持 --strict 模式和宽松模式

4.3 ty 的类型推断引擎

ty 的类型推断引擎基于「约束求解」(Constraint-based Type Inference)方法。与 mypy 的「双向类型检查」(Bidirectional Type Checking)不同,ty 将类型推断建模为一个约束满足问题:

# 对于这段代码
def add(a: int, b: int) -> int:
    return a + b

result = add(1, 2)  # ty 会推断 result: int

ty 会生成以下约束:

  1. add 的参数类型必须匹配 int
  2. add 的返回类型是 int
  3. result 的类型等于 add 的返回类型

然后通过约束求解器求解所有未知类型。这种方法的优势在于可以处理复杂的泛型和联合类型。

4.4 与 mypy 的对比

# 性能对比(Django 项目,约 20 万行代码)
$ time mypy .
real    0m34.521s

$ time ty check .
real    0m0.892s

# 提速 38 倍
# 类型推断能力对比
from typing import Union

def process(x: Union[int, str]) -> str:
    if isinstance(x, int):
        return str(x)
    return x

# mypy: 正确推断
# ty: 正确推断

# 复杂泛型场景
from typing import TypeVar, Generic

T = TypeVar('T')
U = TypeVar('U')

class Box(Generic[T]):
    def __init__(self, value: T) -> None:
        self.value = value
    
    def map(self, f: 'Callable[[T], U]') -> 'Box[U]':
        return Box(f(self.value))

# mypy: 部分场景需要显式注解
# ty: 大多数场景可以自动推断

第五章:配置统一 — pyproject.toml 的终极形态

5.1 一个文件统治一切

Astral 工具链最令人愉悦的特性之一是配置统一。uv、Ruff、ty 的所有配置都可以放在同一个 pyproject.toml 文件里:

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115.0",
    "uvicorn>=0.30.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0",
    "ruff>=0.6.0",
]

[tool.ruff]
target-version = "py312"
line-length = 88

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # pyflakes
    "I",    # isort
    "B",    # flake8-bugbear
    "C4",   # flake8-comprehensions
    "UP",   # pyupgrade
]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["my_project"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.ty]
python-version = "3.12"

对比传统的配置方式:

# 传统方式:4 个配置文件
# .flake8
[flake8]
max-line-length = 88
extend-ignore = E501
per-file-ignores = __init__:F401

# setup.cfg 或 .isort.cfg
[isort]
profile = black
known_first_party = my_project

# pyproject.toml (只有 black)
[tool.black]
line-length = 88
target-version = ["py312"]

# mypy.ini
[mypy]
python_version = 3.12
ignore_missing_imports = True

一个文件 vs 四个文件,这就是 Astral 工具链的配置哲学。

5.2 迁移指南

从传统工具链迁移到 Astral 工具链,推荐的步骤是:

第一步:安装 uv

curl -LsSf https://astral.sh/uv/install.sh | sh

第二步:用 uv 管理依赖

# 将 requirements.txt 转换为 pyproject.toml
uv init
uv add -r requirements.txt

# 如果有 requirements-dev.txt
uv add --dev -r requirements-dev.txt

第三步:用 Ruff 替代 Flake8 + Black + isort

# 安装 Ruff
uv add --dev ruff

# 从 Flake8 迁移规则
# 查看 Ruff 的规则映射表:https://docs.astral.sh/ruff/rules/

# 运行 Ruff 检查
ruff check .

# 运行 Ruff 格式化
ruff format .

第四步:更新 CI 配置

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v4
      - run: uv sync
      - run: uv run ruff check .
      - run: uv run ruff format --check .
      - run: uv run ty check .

第五步:更新 pre-commit

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.6.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

第六章:Ruff 的 Rust 实现细节

6.1 Python 解析器

Ruff 内置的 Python 解析器是一个手写的递归下降解析器(Recursive Descent Parser),直接将 Python 源代码解析为 AST。它支持 Python 3.14 的所有语法特性,包括:

  • 模式匹配(match/case
  • 异步生成器
  • 海象运算符(:=
  • f-string 调试格式(f"{x=}"
  • PEP 695 类型参数语法

解析器的实现使用了 Rust 的零成本抽象——解析过程中不需要分配额外的内存,AST 节点直接存储在连续的内存块中。

6.2 规则的实现模式

每条 Ruff 规则都遵循统一的实现模式:

// 规则定义
pub struct RuleUnusedVariable;

impl Rule for RuleUnusedVariable {
    fn check(&self, ast: &ModModule) -> Vec<Diagnostic> {
        let mut diagnostics = Vec::new();
        
        // 遍历 AST,查找未使用的变量
        for stmt in ast.body.iter() {
            if let Stmt::Assign(assign) = stmt {
                for target in &assign.targets {
                    if let Name(name) = target {
                        if !is_used(name, ast) {
                            diagnostics.push(Diagnostic::new(
                                "F841",
                                format!("Local variable `{name}` is assigned to but never used"),
                                target.range(),
                            ));
                        }
                    }
                }
            }
        }
        
        diagnostics
    }
}

每条规则都是一个独立的结构体,实现了 Rule trait。规则引擎通过动态分发(dynamic dispatch)调用所有注册的规则。

6.3 格式化器的确定性

Ruff 的格式化器追求「确定性」——对于相同的输入,总是产生相同的输出。这是通过以下设计保证的:

  1. 无状态格式化:格式化器不依赖任何外部状态(如文件修改时间、Git 历史)
  2. 规范化的空白处理:所有空白字符(空格、制表符、换行符)都被规范化为统一的形式
  3. Black 兼容的决策树:格式化决策遵循 Black 的规范,确保输出一致
# Ruff 格式化前
x=1;y=2;z=3

# Ruff 格式化后(与 Black 一致)
x = 1
y = 2
z = 3

第七章:生态集成与社区

7.1 IDE 支持

Astral 工具链的 IDE 集成非常成熟:

VS Code

{
  "extensions": [
    "charliermarsh.ruff",
    "astral-sh.ty"
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.ruff": "explicit",
    "source.organizeImports.ruff": "explicit"
  }
}

Neovim(通过 nvim-lspconfig):

require('lspconfig').ruff.setup({})
require('lspconfig').ty.setup({})

PyCharm:通过官方插件支持,可一键启用 Ruff 作为外部工具。

7.2 CI/CD 集成

Ruff 和 uv 都提供了 GitHub Actions 官方 Action:

- uses: astral-sh/ruff-action@v3
  with:
    args: "check --fix"
    
- uses: astral-sh/ruff-action@v3
  with:
    args: "format --check"

7.3 社区生态

Ruff 的社区生态正在快速成长:

  • ruff-vscode:官方 VS Code 扩展
  • ruff-pre-commit:pre-commit 钩子
  • ruff-lsp:语言服务器协议实现
  • ruff-playground:在线试用 Ruff

第八章:性能基准测试

8.1 测试环境

  • 硬件:Apple M3 Pro, 18GB RAM
  • Python 版本:3.12.4
  • Ruff 版本:0.6.0
  • 测试项目:CPython 源代码(约 50 万行)

8.2 Linting 性能

工具首次运行增量运行提速倍数
Flake847.3s32.1s-
Ruff0.85s0.12s55x

8.3 格式化性能

工具首次运行增量运行提速倍数
Black12.5s8.3s-
Ruff0.23s0.04s54x

8.4 包安装性能

工具冷启动缓存命中提速倍数
pip45.2s12.8s-
uv3.1s0.8s14x

8.5 类型检查性能

工具首次运行增量运行提速倍数
mypy34.5s8.2s-
ty0.89s0.15s38x

第九章:Ruff vs 传统工具链的决策矩阵

9.1 什么时候用 Ruff?

强烈推荐的场景

  • 新项目:没有历史包袱,直接用 Ruff
  • CI 优化:需要缩短 CI 时间
  • 大型项目:代码量大,传统工具慢到无法忍受
  • 团队协作:需要统一代码风格,减少争论

可以考虑的场景

  • 已有 Flake8 配置:可以用 Ruff 的 --config 选项兼容大部分配置
  • 需要特定插件:检查 Ruff 是否已实现该规则

暂不推荐的场景

  • 极度依赖 mypy 的高级特性:ty 还在快速迭代中
  • 需要 Python 2 支持:Ruff 只支持 Python 3

9.2 迁移成本评估

维度成本说明
配置迁移大部分配置可直接映射
规则迁移需要检查 Ruff 是否覆盖所需规则
CI 迁移替换命令即可
IDE 迁移安装官方扩展
团队培训Ruff 的 CLI 接口非常直观

第十章:未来展望

10.1 Astral 的路线图

Astral 的目标很明确:成为 Python 开发体验的基础设施

  • uv:正在实现完整的项目管理能力,目标是替代 Poetry/PDM/Hatch
  • Ruff:正在实现更多规则,目标是覆盖 Flake8 + pylint 的所有规则
  • ty:正在完善类型推断引擎,目标是超越 mypy/pyright 的准确性

10.2 对 Python 生态的影响

Astral 工具链的成功正在产生深远的影响:

  1. 加速 Python 的「Rust 化」:越来越多的 Python 工具开始用 Rust 重写(如 Pydantic v2、Polars)
  2. 提升开发者体验:更快的工具意味着更好的开发体验,这有助于 Python 在性能敏感场景下的竞争力
  3. 统一工具生态:Astral 的成功证明了「统一配置」的价值,未来可能会有更多工具采用类似的策略

10.3 对开发者的建议

  1. 现在就开始用 uv:uv 已经足够稳定,而且性能优势明显
  2. 逐步迁移到 Ruff:不需要一次性迁移,可以先在新项目中试用
  3. 关注 ty 的发展:ty 还在快速迭代中,建议关注但不急于在生产环境使用
  4. 保持开放心态:Python 工具链正在快速变化,保持学习和适应的能力

总结

Astral 工具链的出现,标志着 Python 开发体验进入了一个新的时代。

uv 用 Rust 的速度解决了包管理的性能问题,Ruff 用 Rust 的速度终结了代码质量工具的碎片化,ty 用 Rust 的速度挑战了类型检查的性能极限。

这不是一个「用 Rust 重写一切」的盲目追求,而是一个深思熟虑的工程决策:当工具的性能提升 100 倍时,它不仅仅是「更快」,而是改变了使用方式本身

当代码检查的延迟低于人脑的感知阈值时,它就从一种「需要主动触发的任务」变成了「无缝的背景服务」。当包安装从分钟级缩短到秒级时,CI/CD 的反馈循环变得几乎实时。当类型检查可以在保存时即时运行时,渐进式类型标注不再是理论上的最佳实践,而是真正可落地的工作流。

Astral 用 Rust 重写了 Python 的工具链,但更重要的是,他们重新定义了「好的开发工具应该是什么样的」。

对于每一个 Python 开发者来说,现在是拥抱这个变化的最佳时机。


参考资源

  • Ruff 官方文档:https://docs.astral.sh/ruff/
  • uv 官方文档:https://docs.astral.sh/uv/
  • ty 官方文档:https://docs.astral.sh/ty/
  • Astral 博客:https://astral.sh/blog
  • Ruff GitHub:https://github.com/astral-sh/ruff
  • uv GitHub:https://github.com/astral-sh/uv
  • ty GitHub:https://github.com/astral-sh/ty

推荐文章

如何开发易支付插件功能
2024-11-19 08:36:25 +0800 CST
2024年微信小程序开发价格概览
2024-11-19 06:40:52 +0800 CST
Go 接口:从入门到精通
2024-11-18 07:10:00 +0800 CST
pin.gl是基于WebRTC的屏幕共享工具
2024-11-19 06:38:05 +0800 CST
为什么大厂也无法避免写出Bug?
2024-11-19 10:03:23 +0800 CST
Linux 网站访问日志分析脚本
2024-11-18 19:58:45 +0800 CST
程序员茄子在线接单