这些工具的结合使用,不仅能够显著提升个人开发者的工作效率,还能在团队协作中发挥重要作用,帮助开发者更轻松地构建高质量的 Python 项目。随着 Python 生态系统的不断发展,这些工具将成为现代 Python 开发中不可或缺的一部分。
Python 3.11
Python 3.11 和 3.12 都在性能上有所提升,但我们选择了 Python 3.11,因为 3.12 在一些流行的数据科学库(如 NumPy、Pandas)中仍存在不稳定性,可能影响开发效率和代码可靠性。
对于开发者来说,编程中很大一部分时间都花在了处理错误信息上。Python 3.11 在这方面做出了显著改进,特别是引入了
更智能的回溯机制
。与以往版本相比,3.11 的回溯信息不仅会显示错误发生的文件和行号,还会在代码片段中明确标出错误的具体位置,甚至高亮显示问题所在的行和列。这种改进大大简化了调试过程,减少了排查错误的时间。
此外,Python 3.11 还优化了错误信息的可读性,使得类型错误(TypeError)或属性错误(AttributeError)等提示更加直观和详细,帮助开发者更快理解问题本质。这些改进不仅提升了开发效率,也降低了新手的学习门槛。
Python 3.11 在性能和错误处理上的改进,使其成为当前开发的理想选择,显著提升了开发者的工作效率和生活质量。
下面的代码有一个错误。我们想为
data
的第一个元素赋值,但代码却引用了一个不存在的变量
datas
:
data = [1, 4, 8]# the variable datas does not exist! datas[0] = 2
在 Python 3.10 之前的版本中,这会导致错误跟踪,指出变量
datas
不存在:
$ uv run --python 3.9 --no-project mistake.py Traceback (most recent call last): File "/Users/adamgreen/data-science-south-neu/mistake.py" , line 3, in datas[0] = 2 NameError: name 'datas' is not defined
Python 3.11 将其诊断向前推进了两步,还提供了一种解决方案,即变量应改名为
data
,并指出错误发生在哪一行:
$ uv run --python 3.11 --no-project mistake.py Traceback (most recent call last): File "/Users/adamgreen/data-science-south-neu/mistake.py" , line 3, in datas[0] = 2 ^^^^^ NameError: name 'datas' is not defined. Did you mean: 'data' ?
uv
学习 Python 最难的是学会安装和管理 Python
。即使是资深开发人员,也会为管理 Python 的复杂性而苦恼,尤其是当 Python 不是他们的主要语言时。
uv
[1]
是一个功能强大的 Python 版本管理工具,旨在简化开发者在本地环境中管理和切换不同 Python 版本的过程。与传统的 Python 版本管理工具(如 pyenv、miniconda 或通过下载安装程序手动安装 Python)相比,uv 提供了一种更加高效和便捷的解决方案。
主要功能
Python 版本管理
:uv 允许用户轻松安装、切换和管理多个 Python 版本。无论是 Python 3.7、3.8 还是最新的 3.12 版本,uv 都能快速响应并下载所需的版本。
自动下载与安装
:当用户运行指定 Python 版本的命令或脚本时,如果该版本尚未安装,uv 会自动下载并安装所需的 Python 版本。这一功能极大地简化了开发环境的配置过程,避免了手动下载和安装的繁琐步骤。
跨平台支持
:uv 支持多种操作系统,包括 Windows、macOS 和 Linux,确保开发者可以在不同的平台上使用相同的工具来管理 Python 版本。
轻量级与高效
:uv 的设计注重性能,启动速度快,资源占用低,能够在不影响系统性能的情况下高效管理多个 Python 版本。
优势
简化复杂性
:uv 通过自动化 Python 版本的下载和安装,大大减少了开发者在配置开发环境时的工作量。
灵活性
:uv 不仅支持管理 Python 版本,还可以与现有的虚拟环境工具(如 virtualenv 或 venv)结合使用,提供更加灵活的开发环境管理方案。
社区支持
:uv 是一个开源工具,拥有活跃的社区支持,开发者可以通过社区获取帮助、分享经验,并参与工具的改进。
下面的命令使用 Python 3.12 运行 "hello world" 程序:
$ uv run --python 3.12 --no-project python -c "print('hello world')" hello
uv 也是一个用 Python 管理虚拟环境的工具
。它是 venv 或 miniconda 的替代工具。虚拟环境允许不同的 Python 安装并存,这样就可以在本地处理不同的项目。
下面的命令创建了一个 Python 3.11 的虚拟环境:
$ uv venv --python 3.11 Using CPython 3.11.10 Creating virtual environment at: .venv Activate with: source .venv/bin/activate
你需要使用
$ source activate .venv/bin
激活虚拟环境。
uv 也是一个管理 Python 依赖关系和软件包
的工具。它是 pip 的替代品。Pip、Poetry 和 uv 都可以用来安装和升级 Python 软件包。
下面是一个 uv 管理项目的示例
pyproject.toml
:
[project] name = "hypermodern" version = "0.0.1" requires-python = ">=3.11,<3.12" dependencies = [ "pandas>=2.0.0" , "requests>=2.31.0" ] [project.optional-dependencies]test = ["pytest>=7.0.0" ]
将
uv pip install
指向我们的
pyproject.toml
即可安装项目:
$ uv pip install -r pyproject.toml Resolved 11 packages in 1.69s Installed 11 packages in 61ms + certifi==2024.12.14 + charset-normalizer==3.4.0 + idna==3.10 + numpy==2.2.0 + pandas==2.2.3 + python-dateutil==2.9.0.post0 + pytz==2024.2 + requests==2.32.3 + six==1.17.0 + tzdata==2024.2 + urllib3==2.2.3
和 Poetry 一样,uv 可以将依赖关系锁定到
uv.lock
:
$ uv lock Resolved 17 packages in 5ms
uv 也可以用来添加工具,即全局可用的 Python 工具。下面的命令安装了
pytest
工具,我们可以在任何地方使用它:
$ uv tool install --python 3.11 pytest Resolved 4 packages in 525ms Installed 4 packages in 7ms + iniconfig==2.0.0 + packaging==24.2 + pluggy==1.5.0 + pytest==8.3.4 Installed 2 executables: py.test, pytest
这将添加虚拟环境外可用的程序:
$ which pytest /Users/adamgreen/.local /bin/pytest
Tips: 在 direnv 工具中添加
.envrc
,以便在进入目录时自动切换到正确的 Python 版本。
ruff
Ruff
[2]
是一个现代化的、高性能的 Python 代码检查和格式化工具,旨在为开发者提供一种更快、更高效的代码质量保障方案。作为 Black、autopep8、Flake8 和 isort 等传统工具的替代品,Ruff 凭借其独特的设计和强大的功能,正在成为 Python 开发者工具箱中的重要一员。
核心特点
极速性能
:Ruff 的最大亮点是其卓越的性能。由于它是用 Rust 语言编写的,Ruff 在代码分析和格式化方面的速度远超许多基于 Python 的工具。无论是小型项目还是大型代码库,Ruff 都能在几秒内完成代码检查和格式化,显著提升了开发效率。
全面的规则覆盖
:Ruff 不仅支持 Flake8 规则集的大部分内容,还整合了 isort 等其他工具的规则。这意味着开发者可以通过 Ruff 一次性完成代码风格检查、语法错误检测、导入排序等多种任务,而无需依赖多个工具。
高度可配置
:Ruff 提供了灵活的配置选项,允许开发者根据项目需求自定义规则集和行为。无论是启用或禁用特定规则,还是调整格式化风格,Ruff 都能轻松满足不同团队和项目的需求。
轻量级与易集成
:Ruff 的设计注重简洁和易用,无需复杂的依赖或配置即可快速集成到现有项目中。它支持与常见的开发工具(如 VS Code、PyCharm 等)和 CI/CD 流水线无缝集成,帮助开发者在整个开发周期中保持代码质量。
优势
速度与效率
:Ruff 的极速性能使其在处理大型代码库时表现出色,显著减少了等待时间,提升了开发体验。
多功能一体化
:Ruff 集成了多种工具的功能,避免了开发者需要在不同工具之间切换的麻烦,简化了工作流程。
现代化设计
:基于 Rust 的实现不仅带来了性能上的优势,还使 Ruff 更加稳定和可靠,适合现代开发环境的需求。
与现有工具的对比
与 Black 相比
:Ruff 不仅提供了代码格式化功能,还集成了代码检查的能力,功能更加全面。
与 Flake8 相比
:Ruff 的速度更快,且支持更多的规则集,同时避免了 Flake8 需要安装多个插件的复杂性。
与 isort 相比
:Ruff 可以直接处理导入排序问题,而无需额外安装和配置 isort。
下面的代码有三个问题:
data = datas[0] import collections
在同一目录下运行 Ruff 会发现问题:
$ ruff check . ruff.py:1:8: F821 Undefined name `datas` ruff.py:2:1: E402 Module level import not at top of file ruff.py:2:8: F401 [*] `collections` imported but unused Found 3 errors. [*] 1 potentially fixable with the --fix option.
Tips:
在开发过程中,Ruff 在保存文件时运行足够快--确保在文本编辑器中配置了保存时的格式设置
mypy
mypy
[3]
是一个强大的静态类型检查工具,专门为 Python 设计,旨在通过引入类型注解和类型检查机制,提升代码的可靠性和可维护性。它允许开发者在 Python 中实现类型安全,从而减少运行时错误,并提高代码的可读性和可维护性。与传统的动态类型 Python 开发方式不同,mypy 提供了一种更接近静态类型语言的开发体验,类似于 TypeScript 对 JavaScript 的增强。
核心功能
类型注解支持
:mypy 允许开发者在 Python 代码中使用类型注解(Type Annotations),例如变量、函数参数和返回值的类型声明。这些注解不仅提高了代码的可读性,还为静态类型检查提供了基础。
静态类型检查
:mypy 在代码运行之前对类型注解进行静态分析,检查类型是否一致。它可以捕捉到许多在运行时才会暴露的错误,例如类型不匹配、未定义的属性调用等。
渐进式类型
:mypy 支持渐进式类型系统,这意味着开发者可以逐步为现有代码添加类型注解,而不需要一次性重构整个代码库。这种灵活性使得 mypy 非常适合在大型项目或已有项目中引入类型检查。
与 Python 生态系统的兼容性
:mypy 完全兼容 Python 的标准库和第三方库,并且支持许多流行的 Python 框架(如 Django、Flask 等)。此外,mypy 还可以与 IDE(如 VS Code、PyCharm)集成,提供实时的类型检查反馈。
优势
提前发现错误
:mypy 在代码运行之前就能捕捉到类型相关的错误,避免了运行时崩溃或异常。
提高代码可读性
:类型注解使代码的意图更加清晰,开发者可以更容易理解函数和类的输入输出类型。
增强开发工具支持
:mypy 与主流 IDE 和编辑器的集成,提供了实时的类型检查和自动补全功能,显著提升了开发效率。
渐进式采用
:mypy 允许开发者逐步引入类型注解,无需一次性重构整个代码库,降低了采用的门槛。
mypy_error.py
有一个问题--我们试图将一个字符串除以
10
:
def process(user): # line below causes an error user['name' ] / 10 user = {'name' : 'alpha' } process(user)
我们可以通过运行 mypy 来捕获这个错误--捕获错误而不实际执行 Python 代码:
$ mypy --strict mypy_error.py mypy_error.py:1: error: Function is missing a type annotation mypy_error.py:5: error: Call to untyped function "process" in typed context Found 2 errors in 1 file (checked 1 source file)
第一个错误是因为我们的代码没有类型化 - 我们可以添加两个类型注解,使我们的代码类型化:
user: dict[str,str]
-
user
是一个以字符串为键和值的字典、
-> None:
-
process
函数返回
None
。
def process(user: dict[str,str]) -> None: user['name' ] / 10 user = {'name' : 'alpha' } process(user)
在
mypy_intermediate.py
上运行 mypy,mypy 指出了代码中的错误:
$ mypy --strict mypy_intermediate.py mypy_fixed.py:2: error: Unsupported operand types for / ("str" and "int" ) Found 1 error in 1 file (checked 1 source file)
这是一个无需编写任何特定测试逻辑即可运行的测试。
Tips:
在调试类型问题时,在代码中使用
reveal_type(变量)
。mpy 会向你显示它认为变量的类型。
Typer
Typer
[4]
是一个基于 Python 类型提示构建命令行界面 (CLI) 的强大工具,旨在为开发者提供一种更简洁、更直观的方式来创建命令行应用程序。与传统的
sys.argv
或
argparse
相比,Typer 充分利用了 Python 的类型注解功能,使得 CLI 的开发更加高效和易于维护。
核心特点
基于类型提示
:Typer 使用 Python 的类型注解(Type Hints)来定义命令行参数和选项,使得代码更加清晰和类型安全。
自动生成帮助文档
:Typer 会根据类型注解自动生成命令行帮助文档,开发者无需手动编写复杂的帮助信息。
简洁的 API
:Typer 的 API 设计非常简洁,开发者只需几行代码即可实现复杂的命令行功能。
强大的子命令支持
:Typer 支持嵌套子命令,使得开发者可以轻松构建复杂的命令行工具。
与 Click 的兼容性
:Typer 基于 Click 构建,因此完全兼容 Click 的功能,同时提供了更现代化的开发体验。
优势
开发效率高
:Typer 的简洁 API 和自动生成帮助文档的功能显著提升了开发效率。
代码可读性强
:基于类型提示的代码更加清晰和易于理解。
类型安全
:Typer 的类型检查功能可以在开发阶段捕捉到潜在的错误,减少运行时问题。
首先创建一个虚拟环境:
$ uv venv --python=3.11.10 Using CPython 3.11.10 Creating virtual environment at: .venv Activate with: source .venv/bin/activate
然后使用
uv init
从头开始创建一个新项目:
$ uv init --name demo --python 3.11.10 --package Initialized project `demo`
这样就创建了一个项目:
$ tree . ├── pyproject.toml ├── README.md └── src └── demo └── __init__.py
然后,我们可以使用
uv add
将
typer
添加为依赖关系:
$ uv add typer Using CPython 3.11.10 Creating virtual environment at: .venv Resolved 10 packages in 2ms Installed 8 packages in 9ms + click==8.1.8 + markdown-it-py==3.0.0 + mdurl==0.1.2 + pygments==2.18.0 + rich==13.9.4 + shellingham==1.5.4 + typer==0.15.1 + typing-extensions==4.12.2
然后,我们添加修改 Python 文件
src/demo/__init__.py
,使其包含一个简单的 CLI:
import typer app = typer.Typer() @app.command() def main(name: str) -> None: print (f"Hello {name}" )
我们需要将此添加到
pyproject.toml
中,以便使用
demo
命令运行 CLI:
demo = "demo:app"
这是完整的
pyproject.toml
:
[project] name = "demo" version = "0.1.0" description = "Add your description here" readme = "README.md" authors = [ { name = "Adam Green" , email = "[email protected] " } ] requires-python = ">=3.11.10" dependencies = [ "typer>=0.15.1" , ] [project.scripts] demo = "demo:app" [build-system] requires = ["hatchling" ] build-backend = "hatchling.build"
由于我们在
pyproject.toml
中包含了
[project.scripts]
,因此可以使用
uv run
运行此 CLI:
$ uv run demo omega Hello omega
Typer 为我们免费提供了“--help ”标志:
$ python src/demo/__init__.py --help Usage: demo [OPTIONS] NAME ╭─ Arguments ──────────────────────────────────────────────────────────────────────────────────╮ │ * name TEXT [default: None] [required] │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮ │ --install-completion Install completion for the current shell. │ │ --show-completion Show completion for the current shell, to copy it or customize │ │ the installation. │ │ --help Show this message and exit . │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯
Tips: