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       # 父目录
  • 绝对导入:清晰、重构友好
  • 相对导入:包内部使用,保持封装性

模块搜索顺序

  1. 当前目录
  2. PYTHONPATH 环境变量
  3. 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 年的正确姿势——风格指南是给工具读的,不是给人背的。


关联