写 Python 项目不是打开编辑器就敲代码,而是遵循“需求 → 设计 → 实现 → 测试 → 重构”的工程化流程。每次开发新功能时,请严格按以下 6 步执行:
先用自然语言或伪代码描述功能边界、参数类型和返回值。
💡 想清楚再动手,避免写到一半发现方向错误。创建隔离环境,安装所需第三方库并锁定版本。
💡 永远不要在全局环境中安装项目依赖。用 dataclass、TypedDict 或 Pydantic 定义数据契约。
💡 类型提示是现代 Python 的基石,越早写越好。TDD 思维:先写测试用例,再实现函数体,确保可验证。
💡 没有测试的代码就是定时炸弹。组装各模块,添加日志、异常捕获和配置管理。
💡 优雅地处理错误比正常流程更重要。运行 ruff/black 格式化,补充 docstring,更新 CHANGELOG。
💡 代码是写给人看的,顺便给机器执行。Traceback → 变量状态 → 类型匹配 → 逻辑分支 → 外部依赖 逐层定位。
目标:配置开发环境,掌握变量、条件、循环等基础语法。
# 创建虚拟环境
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# hello.py
name: str = input("请输入你的名字: ")
print(f"你好, {name}! 欢迎学习 Python 🐍")
# 变量与类型提示
age: int = 25
score: float = 95.5
is_active: bool = True
# 条件判断
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
else:
grade = "C"
# 循环
for i in range(5):
print(f"第 {i+1} 次循环")
# 列表推导式(Pythonic 写法)
squares: list[int] = [x**2 for x in range(10) if x % 2 == 0]
目标:熟练使用内置数据结构,编写可复用的函数。
| 类型 | 特点 | 典型场景 |
|---|---|---|
| list | 有序、可变、可重复 | 序列数据、栈、队列 |
| dict | 键值对、O(1)查找 | 配置、缓存、JSON映射 |
| set | 无序、去重、集合运算 | 去重、交集/并集判断 |
| tuple | 不可变、可哈希 | 字典键、函数多返回值 |
from typing import Optional
def calculate_bmi(weight: float, height: float) -> float:
"""计算BMI指数
Args:
weight: 体重(kg)
height: 身高(m)
Returns:
BMI值,保留两位小数
"""
if height <= 0:
raise ValueError("身高必须大于0")
return round(weight / (height ** 2), 2)
# 默认参数 + 可选类型
def greet(name: str, greeting: Optional[str] = None) -> str:
prefix = greeting or "你好"
return f"{prefix}, {name}!"
目标:掌握类与对象、继承、模块组织方式。
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class Article:
title: str
content: str
author: str
tags: list[str] = field(default_factory=list)
created_at: datetime = field(default_factory=datetime.now)
@property
def summary(self) -> str:
return self.content[:100] + "..." if len(self.content) > 100 else self.content
def __str__(self) -> str:
return f"[{self.author}] {self.title}"
my_project/
├── pyproject.toml # 项目元数据与依赖
├── src/
│ └── my_project/
│ ├── __init__.py # 包初始化
│ ├── models.py # 数据模型
│ ├── services.py # 业务逻辑
│ └── utils.py # 工具函数
├── tests/
│ └── test_services.py # 单元测试
└── main.py # 入口文件
目标:理解生成器、装饰器、上下文管理器及异步编程。
# 装饰器:增强函数功能
import functools
import time
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} 耗时: {elapsed:.4f}s")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "done"
# 上下文管理器:资源安全释放
from contextlib import contextmanager
@contextmanager
def managed_file(path: str, mode: str):
f = open(path, mode)
try:
yield f
finally:
f.close()
# 生成器:惰性求值,节省内存
def read_large_file(path: str):
with open(path, 'r', encoding='utf-8') as f:
for line in f:
yield line.strip()
import asyncio
import aiohttp
async def fetch_url(url: str) -> str:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = ["https://api.example.com/1", "https://api.example.com/2"]
tasks = [fetch_url(url) for url in urls]
results = await asyncio.gather(*tasks)
for r in results:
print(r[:100])
asyncio.run(main())
# test_services.py
import pytest
from my_project.services import calculate_discount
def test_normal_discount():
assert calculate_discount(100, 0.8) == 80.0
def test_invalid_rate_raises():
with pytest.raises(ValueError, match="折扣率必须在0-1之间"):
calculate_discount(100, 1.5)
# 运行: pytest -v --cov=my_project
| 类别 | 推荐工具 | 用途 |
|---|---|---|
| 包管理 | uv / poetry | 依赖解析、虚拟环境、发布 |
| 格式化 | ruff / black | 代码风格统一、自动修复 |
| 类型检查 | mypy / pyright | 静态类型验证 |
| 测试 | pytest + coverage | 单元测试、覆盖率报告 |
| 文档 | mkdocs-material | 自动生成API文档站点 |
| CI/CD | GitHub Actions | 自动化测试、构建、部署 |
pyproject.toml + .gitignore + README.md + LICENSE + CI配置。
| 阶段 | 核心关键词 | 重点掌握内容 |
|---|---|---|
| 基础 | 语法, 类型提示 | 变量、条件、循环、f-string |
| 结构 | 数据结构, 函数 | list/dict/set、函数签名、docstring |
| OOP | 类, 模块, 包 | dataclass、继承、项目结构 |
| 进阶 | 装饰器, 异步 | 生成器、上下文管理器、asyncio |
| 工程 | 测试, 工具链 | pytest、ruff、mypy、CI/CD |