Python
综合实战与进阶路线
整合任务管理器的领域、数据库、网络、并发、测试与打包,形成可交付项目闭环。
发布于 2026年7月23日
综合实战与进阶路线
本篇把前面的语言与工程能力合并为可安装的 study_tasks 命令行应用。重点不是再堆功能,而是确认模块边界、数据一致性、失败语义和交付流程形成闭环。
一、项目目标
最终命令:
study-tasks add "阅读 Python 文档"
study-tasks list
study-tasks list --status todo
study-tasks done 1
study-tasks delete 1
study-tasks sync
完成标准:
- 标题和状态在领域层保持合法;
- SQLite 写入使用参数与事务;
- 配置由环境变量覆盖 TOML;
- 网络请求有超时、响应验证和明确错误;
- 并发同步有结构化生命周期;
- pytest、Ruff、mypy 全部通过;
- wheel 可在干净 Python 3.14 环境安装运行。
二、最终结构
study_tasks/
pyproject.toml
README.md
src/study_tasks/
__init__.py
models.py 领域对象和状态
config.py TOML、环境变量与默认值
db.py SQLite 仓储
service.py 用例与业务规则
http.py HTTP 同步边界
cli.py 参数、输出和退出码
tests/
test_models.py
test_service.py
依赖方向:
cli -> config
cli -> service -> models
cli -> db -> models
cli -> http -> models
tests -> public interfaces
领域模型不导入 CLI、数据库或网络模块。
三、核心领域模型
from dataclasses import dataclass
from datetime import UTC, datetime
from enum import StrEnum
class TaskStatus(StrEnum):
TODO = "todo"
DONE = "done"
@dataclass(frozen=True, slots=True)
class Task:
id: int
title: str
status: TaskStatus
created_at: datetime
updated_at: datetime
@classmethod
def new(cls, title: str) -> "Task":
clean_title = title.strip()
if not clean_title:
raise ValueError("任务标题不能为空")
now = datetime.now(UTC)
return cls(0, clean_title, TaskStatus.TODO, now, now)
对象只表示合法任务。外部输入先解析验证,再进入领域层。
四、服务与仓储
class TaskService:
def __init__(self, repository: TaskRepository) -> None:
self._repository = repository
def add(self, title: str) -> Task:
return self._repository.add(Task.new(title))
def list(self, status: TaskStatus | None = None) -> list[Task]:
return self._repository.list(status=status)
def complete(self, task_id: int) -> Task:
return self._repository.set_status(
task_id,
TaskStatus.DONE,
datetime.now(UTC),
)
def delete(self, task_id: int) -> None:
self._repository.delete(task_id)
服务描述用例,仓储负责持久化。CLI 不直接拼 SQL,仓储也不打印用户消息。
五、配置契约
study_tasks.toml:
[study_tasks]
database = "tasks.db"
api_url = "https://api.example.com/tasks"
环境变量:
STUDY_TASKS_DB
STUDY_TASKS_API_URL
STUDY_TASKS_API_TOKEN
优先级固定为环境变量、TOML、默认值。Token 不进入 TOML 示例、日志和数据库。
六、迭代顺序
迭代 1:本地闭环
Task与TaskStatus- SQLite 建表、添加、列表、完成、删除
- CLI 子命令和退出码
- 模型与仓储测试
完成标准:离线状态下能管理任务,非法标题和未知 ID 返回明确错误。
迭代 2:可配置与可诊断
- TOML 和环境变量
--verbose- 日志字段与敏感信息白名单
- 配置优先级测试
完成标准:可改变数据库位置,日志不泄露 Token。
迭代 3:网络同步
- HTTP 客户端、超时与 JSON 验证
- 本地测试服务器
TaskGroup并发同步- 并发上限、取消和部分失败策略
完成标准:不依赖公网即可覆盖成功、状态码错误、无效 JSON 和超时。
迭代 4:交付
pyproject.toml与控制台脚本- pytest、Ruff、mypy
- sdist、wheel 和干净环境烟测
- 发布说明与校验和
七、测试矩阵
| 场景 | 预期 |
|---|---|
| 空白标题 | 拒绝且不写数据库 |
| 创建任务 | 返回数据库 ID,状态为 todo |
| 完成任务 | 状态与更新时间一起提交 |
| 未知任务 ID | 返回非零退出码,数据库不变 |
| 配置文件缺失 | 使用默认数据库路径 |
| 环境变量存在 | 覆盖 TOML |
| HTTP 500 | 明确归类为服务端错误 |
| 无效 JSON | 拒绝响应,不修改本地状态 |
| 一个并发任务失败 | 取消同组任务并传播异常组 |
| 安装 wheel | 在源码目录外可运行 study-tasks --help |
八、安全与可靠性检查
- SQL 全部参数化,动态结构只来自程序白名单。
- 网络请求必须使用 HTTPS、有限超时和响应类型检查。
- 日志不包含 Token、完整请求体和用户敏感数据。
- 文件路径不由未验证输入突破允许目录。
- 数据库事务不包含网络等待。
- 批量导入先完整验证,再在一个事务写入。
- 重试只用于暂时性且幂等的操作。
九、性能检查
先测量再优化:
python -m timeit "sum(range(1000))"
python -X importtime -m study_tasks --help
数据库使用真实查询计划检查索引;网络同步测量吞吐、延迟和错误率。不要用并发掩盖慢 SQL,也不要为了微小语法差异牺牲可读性。
需要深入分析时使用 cProfile:
python -m cProfile -s cumulative -m study_tasks list
十、发布检查表
python --version
pytest
ruff check .
ruff format --check .
mypy -p study_tasks
python -m build
python -m zipfile --list dist/study_tasks-0.1.0-py3-none-any.whl
然后在全新虚拟环境安装 wheel,实际执行新增、列表、完成和删除命令。
发布记录至少包含版本、支持的 Python 范围、变更摘要、已知限制、构建产物 SHA-256 和回滚方式。
十一、继续深入
- 性能:profiling、内存分析、缓存与批处理
- 数据库:PostgreSQL、隔离级别、锁和迁移
- 网络:连接池、OAuth2/OIDC、限流和幂等 API
- 并发:队列、背压、任务取消和多进程
- 架构:领域服务、端口适配器和插件系统
- 交付:CI/CD、SBOM、签名、可观测性和供应链安全
- Web 开发:请求响应、模板、ORM、认证和部署
学习下一主题时继续落到项目。例如学习 Web 框架,就把现有 TaskService 暴露为网页和 API,而不是把业务规则重新写进视图。
十二、最终自测
- 名称绑定、可变性和对象身份分别如何影响代码?
- 外部 JSON 如何安全转换为领域对象?
- 为什么事务中不应等待网络?
- 线程、进程和 asyncio 的选择依据是什么?
- 类型检查、测试和运行时校验分别负责什么?
- 如何证明 wheel 在干净环境中可安装运行?
- 如何在不泄露秘密的前提下诊断同步失败?
如果这些问题都能通过代码和测试回答,你已经完成了从“会写 Python 语法”到“能交付 Python 项目”的闭环。
十三、官方资料与下一步
完成语言与工程基础后,可以继续现有的 Django 完整学习路线,把任务领域扩展为带认证、数据库、页面和 API 的 Web 应用。
上一篇:pyproject、打包与发布 | 返回:Python 完整学习路线