摘要:在本文中,我们介绍了几个现代化的 Python 工具,它们各自在提升开发效率、代码质量和用户体验方面发挥着重要作用。uv 作为一个高效的 Python 版本管理工具,帮助开发者轻松管理复杂的开发环境;Ruff 通过其速度和易用性,显著提升了代码质量和开发效率;
在本文中,我们介绍了几个现代化的 Python 工具,它们各自在提升开发效率、代码质量和用户体验方面发挥着重要作用。uv 作为一个高效的 Python 版本管理工具,帮助开发者轻松管理复杂的开发环境;Ruff 通过其速度和易用性,显著提升了代码质量和开发效率;mypy 作为静态类型检查的领先工具,帮助开发者构建更可靠、易维护的代码;Typer 则简化了 CLI 应用程序的开发,结合 uv 的环境管理能力,进一步提升了项目配置和部署的便捷性;最后,Rich 通过美化终端输出,为开发者提供了更直观、美观的调试和展示工具。
这些工具的结合使用,不仅能够显著提升个人开发者的工作效率,还能在团队协作中发挥重要作用,帮助开发者更轻松地构建高质量的 Python 项目。随着 Python 生态系统的不断发展,这些工具将成为现代 Python 开发中不可或缺的一部分。
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.pyTraceback (most recent call last): File "/Users/adamgreen/data-science-south-neu/mistake.py", line 3, in datas[0] = 2NameError: name 'datas' is not definedPython 3.11 将其诊断向前推进了两步,还提供了一种解决方案,即变量应改名为 data,并指出错误发生在哪一行:
$ uv run --python 3.11 --no-project mistake.pyTraceback (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 3.12 运行 "hello world" 程序:
$ uv run --python 3.12 --no-project python -c "print('hello world')"hellouv 也是一个用 Python 管理虚拟环境的工具。它是 venv 或 miniconda 的替代工具。虚拟环境允许不同的 Python 安装并存,这样就可以在本地处理不同的项目。
下面的命令创建了一个 Python 3.11 的虚拟环境:
$ uv venv --python 3.11Using CPython 3.11.10Creating virtual environment at: .venvActivate 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,=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.tomlResolved 11 packages in 1.69sInstalled 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 lockResolved 17 packages in 5msuv 也可以用来添加工具,即全局可用的 Python 工具。下面的命令安装了 pytest 工具,我们可以在任何地方使用它:
$ uv tool install --python 3.11 pytest Resolved 4 packages in 525msInstalled 4 packages in 7ms + iniconfig==2.0.0 + packaging==24.2 + pluggy==1.5.0 + pytest==8.3.4Installed 2 executables: py.test, pytest这将添加虚拟环境外可用的程序:
$ which pytest/Users/adamgreen/.local/bin/pytestTips: 在 direnv 工具中添加 .envrc,以便在进入目录时自动切换到正确的 Python 版本。
ruffRuff[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。下面的代码有三个问题:
我们使用了一个未定义的变量 datas。导入的位置不对。导入了我们不用的东西。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 fileruff.py:2:8: F401 [*] `collections` imported but unusedFound 3 errors.[*] 1 potentially fixable with the --fix option.Tips: 在开发过程中,Ruff 在保存文件时运行足够快--确保在文本编辑器中配置了保存时的格式设置。
mypymypy[3] 是一个强大的静态类型检查工具,专门为 Python 设计,旨在通过引入类型注解和类型检查机制,提升代码的可靠性和可维护性。它允许开发者在 Python 中实现类型安全,从而减少运行时错误,并提高代码的可读性和可维护性。与传统的动态类型 Python 开发方式不同,mypy 提供了一种更接近静态类型语言的开发体验,类似于 TypeScript 对 JavaScript 的增强。
mypy_error.py 有一个问题--我们试图将一个字符串除以 10:
def process(user): # line below causes an error user['name'] / 10user = {'name': 'alpha'}process(user)我们可以通过运行 mypy 来捕获这个错误--捕获错误而不实际执行 Python 代码:
$ mypy --strict mypy_error.pymypy_error.py:1: error: Function is missing a type annotationmypy_error.py:5: error: Call to untyped function "process" in typed contextFound 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'] / 10user = {'name': 'alpha'}process(user)在 mypy_intermediate.py 上运行 mypy,mypy 指出了代码中的错误:
$ mypy --strict mypy_intermediate.pymypy_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 会向你显示它认为变量的类型。
TyperTyper[4] 是一个基于 Python 类型提示构建命令行界面 (CLI) 的强大工具,旨在为开发者提供一种更简洁、更直观的方式来创建命令行应用程序。与传统的 sys.argv 或 argparse 相比,Typer 充分利用了 Python 的类型注解功能,使得 CLI 的开发更加高效和易于维护。
首先创建一个虚拟环境:
$ uv venv --python=3.11.10Using CPython 3.11.10Creating virtual environment at: .venvActivate with: source .venv/bin/activate然后使用 uv init 从头开始创建一个新项目:
$ uv init --name demo --python 3.11.10 --packageInitialized project `demo`这样就创建了一个项目:
$ tree.├── pyproject.toml├── README.md└── src └── demo └── __init__.py然后,我们可以使用 uv add 将 typer 添加为依赖关系:
$ uv add typerUsing CPython 3.11.10Creating virtual environment at: .venvResolved 10 packages in 2msInstalled 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 typerapp = typer.Typer@app.commanddef 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 = "adam.green@adgefficiency.com" }]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 omegaHello omega$ 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: 你可以在 Typer 中使用命令和命令组创建嵌套的 CLI 组。
RichRich[5] 是一个功能强大的 Python 库,专门用于在终端中输出美观、格式化的文本内容。它通过丰富的样式、颜色、表格、进度条等功能,彻底改变了传统 Python 程序单调乏味的终端输出方式,为开发者提供了一种更加直观和优雅的展示方式。无论是调试信息、日志记录,还是数据展示,Rich 都能让你的终端输出焕然一新。
Rich 的特点是打印出漂亮的颜色和表情符号:
import richuser = {'name': 'omega', 'id': 'invalid'}print(f" normal printing\nuser {user}\n")rich.print(f" :wave: rich printing\nuser {user}\n") normal printinguser {'name': 'omega', 'id': 'invalid'} rich printinguser {'name': 'omega', 'id': 'invalid'}如果你对 Rich 感兴趣,可以用 Rich 打印代替内置打印,从而简化代码:
from rich.console import Consolefrom rich.table import Tablefrom rich.progress import trackimport time# 创建 Console 对象console = Console# 输出彩色文本console.print("[bold red]Hello, [green]Rich[/green]![/bold red]")# 创建表格table = Table(title="示例表格")table.add_column("ID", justify="right", style="cyan")table.add_column("名称", style="magenta")table.add_column("描述", style="green")table.add_row("1", "Python", "一种流行的编程语言")table.add_row("2", "Rich", "一个终端美化工具")console.print(table)# 进度条示例for i in track(range(10), description="处理中..."): time.sleep(0.5)此外,Rich 有一个检查功能,可以对任何 Python 对象(例如类、实例或内置对象)生成报告。
my_list = ["foo", "bar"]from rich import inspectinspect(my_list, methods=True)Tips: Rich 提供了比颜色和表情符号更多的功能,包括显示表格数据和更好的 Python 错误回溯。
最后我们对本次分享做个总结:
uv 是一个现代化的 Python 版本管理工具,通过其自动化、高效和跨平台的特点,帮助开发者更轻松地管理复杂的 Python 开发环境。无论是个人开发者还是团队,uv 都能显著提升开发效率和环境配置的便捷性。
Ruff 是一个集速度、功能和易用性于一体的 Python 代码工具,适合希望提升代码质量和开发效率的开发者。无论是个人项目还是团队协作,Ruff 都能成为你的得力助手,帮助你更轻松地编写高质量的 Python 代码。
mypy 作为 Python 静态类型检查的领先工具,正在帮助开发者构建更可靠、更易维护的代码。随着 Python 社区对静态类型的接受度不断提高,mypy 将成为现代 Python 开发中不可或缺的一部分。
Typer 是一个现代化的 Python CLI 开发工具,通过其简洁的 API 和强大的类型提示功能,帮助开发者快速构建高效、易维护的命令行应用程序。结合 uv 的环境管理能力,开发者可以更轻松地配置和部署 Python 项目。无论是个人项目还是团队工具,Typer 都能显著提升开发效率和代码质量。
Rich 是一个现代化的 Python 终端美化工具,通过其丰富的功能和简洁的 API,帮助开发者以更美观、更直观的方式展示终端输出。无论是调试信息、数据展示,还是日志记录,Rich 都能显著提升终端输出的质量和用户体验。如果你厌倦了单调的终端输出,Rich 无疑是你的理想选择。
来源:数据派THU