Python 工程实践
从模块组织到测试、从工具链到风格——Python 工程的完整闭环。
模块与包
Python 中,一个 .py 文件即一个模块。包是包含 __init__.py 的目录(3.3+ 命名空间包可不含)。
导入方式
import module # 导入整个模块
from module import func # 导入指定函数
from module import func as f # 导入并重命名
from module import * # 全部导入(避免使用)绝对导入 vs 相对导入
# 绝对导入——从项目根目录出发
import mypackage.module_a
# 相对导入——从当前模块位置出发
from . import module_a # 同目录
from .. import module_b # 父目录- 绝对导入:清晰、重构友好
- 相对导入:包内部使用,保持封装性
模块搜索顺序
- 当前目录
- PYTHONPATH 环境变量
- Python 安装目录
查看搜索路径:import sys; print(sys.path)
测试
pytest(2026 年事实标准)
# test_calc.py
def test_add():
assert add(1, 2) == 3
def test_divide():
with pytest.raises(ZeroDivisionError):
divide(1, 0)运行:
pytest # 自动发现 test_*.py
pytest -v # 详细输出
pytest --cov=src # 覆盖率(需 pytest-cov)unittest(内置)
import unittest
class TestCalc(unittest.TestCase):
def setUp(self):
self.calc = Calculator()
def test_add(self):
self.assertEqual(self.calc.add(1, 2), 3)
if __name__ == '__main__':
unittest.main()Mock
from unittest.mock import MagicMock, patch
mock = MagicMock()
mock.get_data.return_value = 'mock data'
with patch('module.external_api', return_value='mocked'):
result = my_function()调试
breakpoint() # Python 3.8+,替代 pdb.set_trace()
# pdb 命令:n(ext), s(tep), c(ontinue), p(rint), l(ist), q(uit)命令行调试:python -m pdb script.py
CI 配置示例
# .github/workflows/test.yml
name: Python CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv sync
- run: uv run pytest
- run: uv run ruff check
- run: uv run mypy src工具链(2026 年推荐)
uv — 统一项目管理器 🔴 2026 首选
uv 是 Rust 实现的 Python 包管理器,替代 pip + virtualenv + pip-tools + pyenv:
uv init myproject # 创建项目
uv add requests # 添加依赖
uv add --dev pytest ruff # 开发依赖
uv run python main.py # 在虚拟环境中运行
uv python install 3.12 # 安装 Python 版本
uv sync # 按锁文件安装所有依赖uv 比 pip 快 10-100×,是 2026 年新项目的默认选择。
Ruff — Lint + Format
Ruff 用 Rust 实现,替代 flake8 + isort + black:
ruff check . # lint
ruff check --fix . # 自动修复
ruff format . # 格式化pyproject.toml 配置:
[tool.ruff]
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP"]mypy / Pyright — 类型检查
mypy src/ # 命令行动态检查
# VS Code 中默认用 Pyright/Pylance 提供即时反馈二者可共存——CI 用 mypy 做硬基线,IDE 用 Pyright 做即时反馈。
pyproject.toml — 项目标准配置
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["fastapi", "sqlalchemy"]
[project.optional-dependencies]
dev = ["pytest", "ruff", "mypy"]
[tool.ruff]
line-length = 100
[tool.pytest.ini_options]
testpaths = ["tests"]其他工具
| 工具 | 状态 | 场景 |
|---|---|---|
| Poetry | 仍活跃,uv 竞争 | 库打包/发布(pyproject.toml 主导者) |
| pip | 底层安装器 | uv 未覆盖的特殊场景 |
| pyenv | 部分被 uv 替代 | 复杂版本矩阵(uv 已内置 uv python install) |
| pipenv | 🗄️ 已归档 | 不再推荐新项目 |
| virtualenv | 🗄️ 已归档 | venv 内置 + uv 替代 |
风格指南
PEP 8 — Python 官方规范
核心规则:
- 缩进用 4 个空格(不用 Tab)
- 行长不超过 79 字符(文档字符串 72)
- 导入在文件顶部,分三组:标准库 → 第三方 → 本地
- 类名用
CapWords,函数/变量用snake_case - 常量用
UPPER_CASE
工具强制 vs 手动遵守
不要手动记规则,交给工具:
ruff format . # Ruff 自动格式化
ruff check . # Ruff 检查风格违规这才是 2026 年的正确姿势——风格指南是给工具读的,不是给人背的。
关联
- meta: 包管理与工具链 — 跨语言工具链对比
- TypeScript: 工程实践 — pnpm/Biome/Vitest 对照