【AGENT开发】python学习 Python Level 5

每次课 2 小时,共 20 小时 · 从"能写代码"到"能交付项目",通过 Level 5 晋级标准


核心 20% 内容(7 项)

帕累托法则:掌握以下 7 项,就能完成 Level 5 的 80% 练习。其余内容(CI/CD、日志系统、性能监控、ORM/数据库迁移、认证授权、WebSocket、async/await 等)在练习中自然接触或属于进阶方向,不需要在 Level 5 单独花大量时间学。

|----|-----------------------------------------|---------------------------|-------|
| 序号 | 核心知识 | 为什么重要 | 对应课程 |
| 1 | Git 基本操作(init/add/commit/push/pull) | 版本控制是工程化的第一课,不会 Git 无法协作 | S1-S2 |
| 2 | pytest 测试框架(assert/fixture/parametrize) | 测试是"能跑"和"能交付"的分界线 | S3-S4 |
| 3 | requests HTTP 库 | 现代 Web 开发的基础,调用 API 的标准方式 | S5 |
| 4 | Flask 构建 REST API | 从"用 API"到"造 API"的关键一步 | S6 |
| 5 | .env 环境变量与配置管理 | 敏感信息不入代码是生产级项目的底线 | S7 |
| 6 | 项目结构与打包(init.py / requirements.txt) | 从"单文件脚本"到"可维护项目" | S8 |
| 7 | Docker 基础部署 | "在我机器上能跑"和"在任何机器上都能跑"的区别 | S9 |


Session 1:Git 基础 --- 版本控制入门

时间分配

|------|-------|----------------------------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 30min | Git 是什么、init/add/commit/status/log/diff、.gitignore |
| 动手练习 | 60min | 初始化仓库、多次提交、查看历史 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • Git 安装与配置:git config --global user.name "名字"git config --global user.email "邮箱"
  • git init:初始化 Git 仓库
  • git add <file> / git add .:暂存修改到暂存区
  • git commit -m "消息":将暂存区的修改提交到仓库
  • git status:查看工作区状态
  • git log / git log --oneline --graph:查看提交历史
  • git diff:查看未暂存的修改
  • .gitignore 文件:指定 Git 忽略的文件和目录

练习任务

  1. 初始化项目 :创建一个 my_project 目录,git init,创建 README.md 写一行项目介绍,git add + git commit
  1. 多次修改 :修改 README.md 三次,每次 git add + git commit,用 git log --oneline 查看历史
  1. .gitignore :创建 .gitignore 文件,忽略 __pycache__/.env*.pyc,创建这些文件后 git status 确认被忽略
  1. 查看差异 :修改 README.md 但不提交,用 git diff 查看修改内容

学习资源

复盘问题

  1. git addgit commit 的区别是什么?为什么需要两步而不是一步?
  1. git status 输出中 "Changes to be committed" 和 "Changes not staged for commit" 有什么区别?
  1. .gitignore 的作用是什么?为什么 .env 文件不应该被提交到 Git?
  1. git log --oneline --graphgit log 的输出有什么区别?

Session 2:Git 分支与远程协作

时间分配

|------|-------|---------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 30min | 分支概念、branch/checkout/merge、远程仓库 |
| 动手练习 | 60min | 分支开发、GitHub 推送、冲突解决 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • git branch:查看/创建分支
  • git checkout <branch> / git switch <branch>:切换分支
  • git checkout -b <branch> / git switch -c <branch>:创建并切换分支
  • git merge <branch>:合并分支
  • GitHub:创建远程仓库
  • git remote add origin <url>:添加远程仓库
  • git push -u origin main:推送到远程
  • git pull:拉取远程更新
  • git clone <url>:克隆远程仓库
  • 合并冲突:手动编辑冲突文件,git add + git commit

练习任务

  1. 分支开发 :在 main 分支创建项目,创建 feature/login 分支,在分支上添加 login.py,合并回 main
  1. GitHub 推送 :在 GitHub 创建仓库,git remote add origin,推送项目
  1. 制造冲突 :在本地和 GitHub 上同时修改同一行,git pull 制造冲突,手动解决后提交
  1. 克隆项目:克隆一个 GitHub 开源项目到本地,查看其提交历史

学习资源

复盘问题

  1. git mergegit rebase 有什么区别?新手应该用哪个?
  1. 什么情况下会产生合并冲突?怎么解决?
  1. git pushgit pull 分别做什么?为什么团队协作时 pull 很重要?
  1. 为什么不建议直接在 main 分支上开发?

Session 3:pytest 测试基础

时间分配

|------|-------|----------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 30min | pytest 安装、测试函数、assert、运行测试 |
| 动手练习 | 60min | 编写测试、运行测试、分析失败 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • 安装:pip install pytest
  • 测试函数命名:必须以 test_ 开头
  • 测试文件命名:test_*.py*_test.py
  • assert 语句:assert 条件assert 条件, "错误消息"
  • 运行测试:pytest(运行所有)、pytest test_file.py(指定文件)
  • 常用参数:

    • -v:详细输出
    • -k "表达式":只运行匹配的测试
    • --tb=short:简短错误回溯
    • -s:显示 print 输出
  • 测试目录约定:tests/ 目录

练习任务

  1. 计算器测试 :写一个 calculator.py(add, subtract, multiply, divide 函数),在 tests/test_calculator.py 中为每个函数写测试
  1. 故意失败:写一个故意错误的测试,运行 pytest 观察 failure 输出,理解 assertion error
  1. 过滤测试 :用 pytest -k "add" 只运行名字包含 "add" 的测试
  1. 测试 Level 3:为 Level 3 写过的某个类(如 Student 类)编写测试

学习资源

复盘问题

  1. 为什么测试函数必须以 test_ 开头?不以 test_ 开头会怎样?
  1. assert a == bif a != b: raise AssertionError 有什么区别?为什么用 assert
  1. pytest -k "add or subtract" 会运行哪些测试?
  1. --tb=short 和默认的 traceback 有什么区别?什么场景下用哪个?

Session 4:pytest 进阶 --- fixture 与 TDD

时间分配

|------|-------|-----------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 35min | fixture、parametrize、TDD 流程 |
| 动手练习 | 55min | TDD 开发密码验证器、fixture 和 parametrize |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • @pytest.fixture:定义测试夹具(提供测试数据/环境)
  • fixture scope:function(默认)、modulesession
  • @pytest.mark.parametrize:参数化测试,用一个测试函数测多组数据
  • conftest.py:共享 fixture,自动被 pytest 发现
  • @pytest.mark.skip / @pytest.mark.xfail:跳过/预期失败
  • TDD 流程:Red(写测试,失败)→ Green(写代码,通过)→ Refactor(重构)

练习任务

  1. TDD 密码验证器 :用 TDD 方式开发 PasswordValidator 类,至少 5 条规则(长度 ≥ 8、含大写、含数字、含特殊字符、不含空格),每条规则先写测试再写代码
  1. fixture 练习 :用 @pytest.fixture 提供测试用户数据,多个测试函数复用
  1. parametrize 练习 :用 @pytest.mark.parametrize 测试 divide 函数的多组输入输出,包括除以零的情况
  1. conftest.py :创建 conftest.py,定义共享 fixture(如临时目录),在多个测试文件中使用

学习资源

复盘问题

  1. fixture 和直接在测试函数里创建数据有什么区别?什么时候用 fixture?
  1. scope="function"scope="module" 的 fixture 有什么区别?对性能有什么影响?
  1. @pytest.mark.parametrize 相比写多个测试函数有什么优势?
  1. TDD 的"先写测试"为什么能提高代码质量?如果先写代码再补测试,效果有什么不同?

Session 5:requests 库 --- HTTP 客户端

时间分配

|------|-------|-----------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 30min | HTTP 基础、GET/POST、requests 库 |
| 动手练习 | 60min | 调用 API、解析 JSON、异常处理 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • 安装:pip install requests
  • requests.get(url):发送 GET 请求
  • requests.post(url, json=data):发送 POST 请求
  • response.json():将 JSON 响应解析为 Python 字典/列表
  • response.status_code:HTTP 状态码(200 成功、404 未找到、500 服务器错误)
  • response.text:原始文本响应
  • 查询参数:requests.get(url, params={"key": "value"})
  • 请求头:requests.get(url, headers={"Authorization": "Bearer xxx"})
  • 超时:requests.get(url, timeout=5)
  • 异常处理:requests.exceptions.ConnectionErrorTimeoutHTTPError

练习任务

  1. 获取用户列表 :调用 https://jsonplaceholder.typicode.com/users,打印所有用户的姓名和邮箱
  1. 查询参数 :调用 https://jsonplaceholder.typicode.com/posts?userId=1,获取特定用户的帖子
  1. POST 请求 :向 https://jsonplaceholder.typicode.com/posts 发送 POST 请求,创建一篇新帖子
  1. 异常处理 :包装一个 safe_get(url) 函数,处理超时、连接错误和 HTTP 错误

学习资源

复盘问题

  1. response.json()response.text 有什么区别?什么时候用哪个?
  1. 为什么每次请求都应该设置 timeout?不设置会发生什么?
  1. GET 和 POST 的区别是什么?什么时候应该用 POST?
  1. 常见的 HTTP 状态码 200、201、400、404、500 分别代表什么?

Session 6:Flask --- 构建 REST API

时间分配

|------|-------|-----------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 35min | Flask 基础、路由、JSON 响应、HTTP 方法 |
| 动手练习 | 55min | 构建 CRUD API |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • 安装:pip install flask
  • 创建应用:app = Flask(__name__)
  • 路由:@app.route('/path')
  • JSON 响应:jsonify({"key": "value"})
  • HTTP 方法:@app.route('/path', methods=['GET', 'POST'])
  • 路由参数:@app.route('/users/<int:user_id>')
  • 请求体:request.get_json()
  • 查询参数:request.args.get('key')
  • 运行开发服务器:app.run(debug=True, port=5000)

练习任务

  1. Hello World :创建 Flask 应用,/ 返回 {"message": "Hello, World!"}
  1. 用户列表 API :创建内存中的用户列表,GET /api/users 返回所有用户
  1. 创建用户POST /api/users,从 request.get_json() 获取数据,添加到列表,返回 201 状态码
  1. 单个用户GET /api/users/<int:user_id> 返回单个用户,不存在返回 404

学习资源

复盘问题

  1. @app.route('/api/users')@app.route('/api/users/')(尾部斜杠)有什么区别?
  1. jsonify() 和直接 return {"key": "value"} 有什么区别?Flask 2.0+ 有什么变化?
  1. debug=True 在开发时有什么用?为什么绝对不能在生产环境使用?
  1. request.get_json() 什么时候返回 None?怎么处理?

Session 7:环境变量与配置管理

时间分配

|------|-------|---------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 30min | 环境变量、.env 文件、python-dotenv、配置模式 |
| 动手练习 | 60min | 重构代码、创建配置类 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • 环境变量读取:os.environ['KEY'] / os.getenv('KEY', 'default')
  • .env 文件:KEY=value 格式
  • python-dotenvfrom dotenv import load_dotenv; load_dotenv()
  • .gitignore 确保 .env 不被提交
  • 配置类模式:

    复制代码
  • 12-Factor App 原则:配置存储在环境变量中

练习任务

  1. 创建 .env :创建 .env 文件,写入 API_KEY=your_keyDATABASE_URL=sqlite:///app.db
  1. 加载配置 :用 python-dotenv 加载 .env,在代码中读取环境变量
  1. 重构 requests 代码:把 S5 的 API key 从硬编码改为从环境变量读取
  1. 配置类 :创建 config.py,定义 DevelopmentConfigProductionConfig,在 Flask 中使用

学习资源

复盘问题

  1. 为什么不应该把 API key 和数据库密码硬编码在代码里?
  1. .env 文件为什么不能提交到 Git?如果已经提交了怎么补救?(提示:git filter-branch 或 BFG)
  1. os.getenv('KEY', 'default') 的第二个参数有什么用?什么时候用?
  1. 12-Factor App 的配置原则是什么?为什么推荐环境变量而不是配置文件?

Session 8:项目结构与打包

时间分配

|------|-------|-------------------------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 35min | 包结构、init.py、requirements.txt、pyproject.toml |
| 动手练习 | 55min | 重构项目结构、写 README |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • Python 包:目录含 __init__.py 即为包
  • 标准项目结构:

    复制代码
  • requirements.txtpip freeze > requirements.txt
  • pyproject.toml:现代项目元数据格式
  • README.md:项目说明、安装步骤、使用方法
  • 绝对导入 vs 相对导入:from app.routes import xxx vs from .routes import xxx
  • __main__.py:支持 python -m my_package 运行

练习任务

  1. 重构项目:将 S6 的 Flask 应用重构为标准包结构(app/ 包、tests/ 目录)
  1. 依赖管理 :创建 requirements.txt,用 pip freeze > requirements.txt 导出依赖
  1. README :写一个完整的 README.md,包含项目介绍、安装步骤(pip install -r requirements.txt)、运行方法
  1. 模块运行 :添加 __main__.py,用 python -m my_app 运行

学习资源

复盘问题

  1. __init__.py 的作用是什么?空文件和有内容的 __init__.py 有什么区别?
  1. 绝对导入(from app.routes import xxx)和相对导入(from .routes import xxx)有什么区别?应该用哪个?
  1. requirements.txtpyproject.toml 有什么区别?现代项目应该用哪个?
  1. python -m my_package 和直接 python run.py 有什么区别?为什么推荐 -m

Session 9:部署基础 --- Docker 入门

时间分配

|------|-------|-------------------------------|
| 阶段 | 时长 | 内容 |
| 概念学习 | 40min | Docker 概念、Dockerfile 语法、构建与运行 |
| 动手练习 | 50min | Docker 化 Flask 应用 |
| 复盘 | 30min | 回答复盘问题 |

掌握内容

  • Docker 概念:镜像(image)= 模板,容器(container)= 运行实例
  • Dockerfile 常用指令:

    • FROM python:3.12-slim:基础镜像
    • WORKDIR /app:工作目录
    • COPY . /app:复制文件
    • RUN pip install -r requirements.txt:安装依赖
    • EXPOSE 5000:声明端口
    • CMD ["python", "run.py"]:启动命令
  • 构建镜像:docker build -t myapp .
  • 运行容器:docker run -p 5000:5000 myapp
  • 端口映射:-p 主机端口:容器端口
  • 环境变量:docker run -e KEY=value--env-file .env
  • .dockerignore:类似 .gitignore,排除不需要的文件

练习任务

  1. 编写 Dockerfile:为 S6 的 Flask 应用编写 Dockerfile
  1. 构建镜像docker build -t my-flask-app .
  1. 运行容器docker run -p 5000:5000 my-flask-app,在浏览器访问 http://localhost:5000
  1. 环境变量注入 :用 docker run -e API_KEY=xxx -p 5000:5000 my-flask-app 注入环境变量

学习资源

复盘问题

  1. Docker 镜像和容器有什么区别?用一句话解释。
  1. COPY . /appADD . /app 有什么区别?应该用哪个?
  1. 为什么需要 .dockerignore?不用会导致什么问题?
  1. docker run -p 5000:5000 中的两个 5000 分别代表什么?如果只写一个会怎样?

Session 10:结业项目 --- 完整 Web 应用

时间分配

|------|-------|-------------------------|
| 阶段 | 时长 | 内容 |
| 项目规划 | 20min | 确定项目需求、设计 API 端点、规划项目结构 |
| 开发实现 | 70min | 编写代码、写测试、调试 |
| 部署 | 20min | Docker 化、运行 |
| 复盘 | 10min | 自检晋级标准 |

项目:天气查询 Web 应用

功能要求
  1. API 端点

    • GET /api/weather/<city>:查询城市天气(调用外部天气 API)
    • GET /api/history:返回查询历史
    • GET /api/health:健康检查端点
  1. 测试:至少 5 个测试用例(含 fixture 和 parametrize)
  1. 配置 :API key 存储在 .env
  1. 结构:标准包结构
  1. 部署:Dockerfile + docker run
评分标准
  • 项目结构规范(app/ 包、tests/ 目录、README.md、requirements.txt)
  • 至少 3 个 API 端点,返回正确的 JSON 响应
  • 至少 5 个测试用例,全部通过
  • API key 从 .env 读取,不硬编码
  • Git 提交历史清晰(至少 5 次有意义的 commit)
  • Dockerfile 可构建,容器可运行
  • 浏览器能访问 http://localhost:5000/api/weather/Beijing
  • 不查教程独立完成

学习资源

  • wttr.in(更简单的天气 API,无需 key)

复盘问题

  1. 回顾整个 Level 5,哪个 Session 最难?为什么?
  1. 如果让你重新设计这个项目,你会做什么改变?
  1. 你觉得自己最薄弱的环节是什么?怎么补?
  1. 你现在能独立搭建一个 Flask + Docker 的项目吗?如果不能,卡在哪里?

常见错误速查表

|----|-------------------------------|---------------------------------|-----------------------------------------------------|
| # | 错误 | 场景 | 正确做法 |
| 1 | git commit 前忘记 git add | 修改了文件但没暂存 | commit 前先 git status 检查 |
| 2 | .env 提交到 Git | API key 泄露 | .gitignore 中加 .env;如已提交用 git rm --cached .env |
| 3 | 测试函数不以 test_ 开头 | pytest 不运行该测试 | 函数名必须 test_ 前缀 |
| 4 | assert if x > 0 | 语法错误 | assert x > 0(assert 后跟表达式,不跟 if) |
| 5 | response.json 少写 () | 拿到方法对象而非字典 | response.json()(加括号调用) |
| 6 | requests 不设 timeout | 网络问题导致永久阻塞 | requests.get(url, timeout=5) |
| 7 | Flask debug=True 部署到生产 | 交互式调试器暴露,可执行任意代码 | 生产环境用 app.run(debug=False) 或用生产服务器 |
| 8 | 密钥硬编码在代码里 | 安全风险 | 用 .env + os.getenv() |
| 9 | Dockerfile 没有 .dockerignore | 镜像包含 .git__pycache__ 等无用文件 | 创建 .dockerignore 排除不必要文件 |
| 10 | docker run 忘记 -p | 容器内服务运行但外部无法访问 | docker run -p 5000:5000 myapp |


晋级标准自检表

Level 5 是五级路线图的最终等级。以下 10 项全部打勾才算 Level 5 过关:

    1. 能用 Git 管理项目,包括分支创建、合并、远程推送
    1. 能用 pytest 编写测试,使用 assert@pytest.fixture@pytest.mark.parametrize
    1. 理解 TDD 流程,能先写测试再写实现代码
    1. 能用 requests 调用 REST API,处理 JSON 响应和异常
    1. 能用 Flask 构建包含 GET/POST 的 REST API,返回正确的 JSON 和状态码
    1. 能正确使用 .env 管理配置,不硬编码敏感信息
    1. 能将项目组织成标准包结构,含 tests/ 目录和 README.md
    1. 能编写 Dockerfile 并用 docker build + docker run 运行应用
    1. 能用 Git 管理完整开发流程(分支开发 → 提交 → 合并 → 推送)
    1. 能独立完成 S10 结业项目,不查教程

如果任何一项未达标:回到对应 Session 重新练习,不要跳过。Level 5 的核心不是学新语法,而是工程化思维------这些能力在真实项目中每天都在用。

相关推荐
神经蛙199615 小时前
🌍 别再硬编码中文了!Python Web 项目国际化(i18n)完全指南
后端·python
颜酱15 小时前
14 | 验证并修正 LLM 生成的 SQL
人工智能·python
颜酱16 小时前
13 | 使用 LangChain 生成 SQL
人工智能·python·langchain
实验如有神祝女士16 小时前
不同参数规模大模型在医学翻译场景的适配差异
论文阅读·人工智能·深度学习·学习·算法·语言模型·论文笔记
PieroPc16 小时前
Python 写的 Windows凭据添加工具 第二版 解决Win11 23H2, 25H2,26H1,共享文件和打印 一部份问题,不是全部!
开发语言·windows·python
颜酱16 小时前
12 | 组装 SQL 生成上下文
人工智能·python
The_Ticker17 小时前
大宗商品行情API接入教程
开发语言·python·websocket·程序人生·区块链
用户83562907805117 小时前
如何使用 Python 合并多个 Excel 文件
后端·python
颜酱17 小时前
11 | 合并过滤召回结果 - 确定需要的表、字段和指标
人工智能·python
circuitsosk17 小时前
AI系统的效果评测体系:从离线指标到线上业务反馈闭环
人工智能·python