Python 从零到精通验收清单
Python 不能只学成“语法简单、会写脚本”。真正能在商业项目里使用 Python,需要能解释代码为什么这样写、运行时怎么工作、不这样会出什么问题、线上怎么排查,并能把 Python 用到脚本工具、Web API、数据库、数据清洗、自动化、测试和 AI 工程中。
本页是 Python 模块的总验收清单。它不替代单个知识点页,而是把所有知识串成“零基础能学会、进阶能懂原理、项目能落地、面试能回答、线上能排查”的完整路线。
最终学习目标
学完 Python 模块,至少要能做到:
| 能力 | 合格标准 | 不合格表现 |
|---|---|---|
| 环境依赖 | 能创建虚拟环境、固定依赖、解释全局安装风险 | 本地能跑,服务器不能跑 |
| 基础语法 | 能解释执行顺序、缩进、变量引用、类型转换 | 只会复制 print |
| 数据结构 | 能区分 list、tuple、dict、set 的场景和坑 | 所有数据都用 list |
| 函数模块 | 能拆函数、模块、包,理解导入和入口 | 所有代码写一个文件 |
| 面向对象 | 能用类、dataclass、组合表达业务模型 | 为了 OOP 硬继承 |
| 异常文件 | 能处理异常、资源关闭、编码、大文件 | 空 except 吞错误 |
| 类型标注 | 能写清函数契约,理解运行时不强校验 | 类型注释和实际返回不一致 |
| 并发异步 | 能区分线程、进程、asyncio、GIL、背压 | async 里调用阻塞库 |
| Web API | 能解释 Uvicorn、ASGI、FastAPI、Pydantic 请求链路 | 接口函数里直接拼 SQL |
| 数据库 | 能处理事务、连接池、参数绑定、Session 生命周期 | 全局复用连接或拼接 SQL |
| 数据处理 | 能用 Pandas 建可信清洗流程 | 报表对不上不知道查哪里 |
| 工程质量 | 能写日志、测试、配置、项目结构、CLI | 只靠 print 和手工测试 |
| AI 开发 | 能解释 RAG、Embedding、权限过滤、评估和成本 | 只调通模型 API |
| 生产排查 | 能按日志、异常、性能、依赖、数据口径定位 | 出错只重跑脚本 |
总学习路线
flowchart TD
A["环境和运行方式"] --> B["语法、变量、控制流"]
B --> C["数据结构和对象引用"]
C --> D["函数、模块、包"]
D --> E["面向对象和数据建模"]
E --> F["异常、文件、JSON、CSV"]
F --> G["类型标注、日志、测试"]
G --> H["并发、异步、GIL、背压"]
H --> I["FastAPI、数据库、工程分层"]
I --> J["CLI、爬虫、自动化"]
J --> K["NumPy、Pandas、数据处理"]
K --> L["Python AI 工程"]
L --> M["生产排查和面试闭环"]学习顺序不要从 AI 或框架开始。框架只是把基础能力组合起来:变量、函数、异常、文件、类型、日志、测试、网络、数据库都不扎实,写出来的 AI 或 Web 项目会“能跑但不可维护”。
阶段一:环境、解释器和依赖
是什么
Python 程序运行依赖三个层次:
- Python 解释器:负责执行
.py文件。 - 虚拟环境:隔离项目依赖。
- 依赖清单:记录项目需要哪些第三方库。
flowchart TD
A["python 命令"] --> B["解释器版本"]
B --> C["虚拟环境 .venv"]
C --> D["安装依赖"]
D --> E["运行项目代码"]为什么需要虚拟环境
如果把依赖都装到全局环境:
- A 项目升级
pandas可能导致 B 项目报错。 - 本地和服务器依赖版本不一致。
- 不知道项目到底依赖哪些包。
- 删除或迁移项目时很难清理。
Demo:标准环境准备
python -m venv .venv
.venv\Scripts\activate
python -m pip install --upgrade pip
pip install fastapi uvicorn pytest
pip freeze > requirements.txt生产建议:
| 文件 | 作用 |
|---|---|
requirements.txt | 固定依赖版本 |
.env.example | 示例配置,不放真实密钥 |
.gitignore | 忽略 .venv、.env、缓存 |
README.md | 说明如何运行、测试、部署 |
阶段二:Python 程序如何执行
Python 运行 .py 文件时,会按从上到下的顺序执行顶层语句。函数定义本身只是创建函数对象,函数体不会立即执行,直到被调用。
flowchart TD
A["python app.py"] --> B["启动解释器"]
B --> C["读取文件"]
C --> D["解析语法"]
D --> E["执行顶层语句"]
E --> F["遇到函数定义创建函数对象"]
F --> G["调用 main 才执行函数体"]程序入口 Demo
def calculate_total(price: float, count: int) -> float:
return price * count
def main() -> None:
total = calculate_total(19.9, 3)
print(f"总价: {total:.2f}")
if __name__ == "__main__":
main()if __name__ == "__main__" 的作用是:这个文件被直接运行时执行 main(),被别的模块导入时不自动执行主流程。
阶段三:变量、对象引用和可变对象
Python 变量本质是名字绑定对象,不是把值装进固定盒子。
flowchart TD
A["变量 a"] --> C["列表对象 [1,2]"]
B["变量 b"] --> C
C --> D["b.append(3)"]
D --> E["a 也能看到变化"]可变对象坑 Demo
def add_item(item: str, bucket: list[str] = []) -> list[str]:
bucket.append(item)
return bucket
print(add_item("A"))
print(add_item("B"))这个函数第二次会输出 ["A", "B"],因为默认参数只在函数定义时创建一次。正确写法:
def add_item(item: str, bucket: list[str] | None = None) -> list[str]:
if bucket is None:
bucket = []
bucket.append(item)
return bucket不理解会怎样
| 问题 | 后果 |
|---|---|
| 不懂引用 | 修改一个列表影响另一个变量 |
| 不懂可变默认参数 | 多次调用互相污染 |
| 不懂浅拷贝 | 嵌套对象仍共享 |
| 不懂类型转换 | 用户输入字符串参与数字计算报错 |
阶段四:数据结构选择
| 结构 | 特点 | 适合 |
|---|---|---|
list | 有序、可变、可重复 | 结果列表、批量数据 |
tuple | 有序、不可变 | 固定返回值、坐标、只读结构 |
dict | key-value 映射 | 按 ID 查对象、配置、索引 |
set | 去重、集合运算 | 去重、交并差 |
Demo:用 dict 建索引
users = [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
]
user_index = {user["id"]: user for user in users}
print(user_index[2]["name"])如果每次都遍历 list 查 ID,数据量大时会慢;用 dict 可以把“按 ID 查找”变成更直接的映射。
阶段五:函数、模块、包和工程拆分
函数负责把一段明确逻辑封装起来,模块负责把相关函数放在一个 .py 文件,包负责把多个模块组织成目录。
flowchart TD
A["项目"] --> B["api 模块"]
A --> C["service 模块"]
A --> D["repository 模块"]
A --> E["utils 模块"]
C --> D
B --> C不拆模块会怎样
- 一个文件几千行,定位困难。
- 函数互相依赖,无法单测。
- Web、数据库、业务规则混在一起。
- 改一个小需求影响全文件。
推荐分层
app/
api/
services/
repositories/
schemas/
models/
core/
tests/阶段六:面向对象和数据建模
Python 面向对象不是为了“所有代码都写成类”,而是当数据和行为需要放在一起表达时使用。
dataclass Demo
from dataclasses import dataclass
from decimal import Decimal
@dataclass(frozen=True)
class OrderItem:
sku_id: str
price: Decimal
count: int
def amount(self) -> Decimal:
return self.price * self.countfrozen=True 让对象不可变,适合表达导入后的明细、配置快照、值对象。
继承和组合
继承适合明确的“is-a”关系;组合适合“has-a”关系。商业项目里很多场景组合比继承更稳。
class CsvParser:
def parse(self, path: str) -> list[dict]:
...
class ImportService:
def __init__(self, parser: CsvParser):
self.parser = parser阶段七:异常、文件和资源管理
异常不是错误的敌人,而是错误的表达方式。好的异常处理要保留上下文,不要吞掉问题。
文件读取 Demo
from pathlib import Path
import json
def load_config(path: str) -> dict:
file_path = Path(path)
try:
with file_path.open("r", encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError as exc:
raise RuntimeError(f"配置文件不存在: {file_path}") from exc
except json.JSONDecodeError as exc:
raise RuntimeError(f"配置文件不是合法 JSON: {file_path}") from exc大文件处理
不要一次性 read() 全部内容,可以逐行或分块处理。
def count_lines(path: str) -> int:
count = 0
with open(path, "r", encoding="utf-8") as f:
for _ in f:
count += 1
return count阶段八:类型标注、日志和测试
类型标注
类型标注是函数契约,不是运行时强制检查。
def normalize_phone(phone: str) -> str:
return phone.strip().replace(" ", "")它的价值:
- 让调用方知道传什么、返回什么。
- IDE 能提示。
- 静态检查工具能提前发现错误。
- 大项目重构更安全。
logging
import logging
logger = logging.getLogger(__name__)
def import_file(batch_id: str, path: str) -> None:
logger.info("start import batch_id=%s path=%s", batch_id, path)
try:
# 处理文件
logger.info("finish import batch_id=%s", batch_id)
except Exception:
logger.exception("import failed batch_id=%s path=%s", batch_id, path)
raise正式项目不要长期用 print 当日志。日志要有 request_id、batch_id、耗时、错误码和关键业务 ID。
pytest Demo
def normalize_status(status: str) -> str:
mapping = {"启用": "ENABLED", "停用": "DISABLED"}
if status not in mapping:
raise ValueError(f"未知状态: {status}")
return mapping[status]import pytest
def test_normalize_status_enabled():
assert normalize_status("启用") == "ENABLED"
def test_normalize_status_unknown():
with pytest.raises(ValueError):
normalize_status("未知")覆盖率高不等于测试好。好的测试要有明确断言,覆盖业务边界和异常分支。
阶段九:并发、异步、GIL 和背压
怎么选
| 方式 | 适合 | 不适合 |
|---|---|---|
| 线程池 | 阻塞 IO、调用接口、读文件 | CPU 密集计算 |
| 进程池 | CPU 密集计算 | 大量共享内存状态 |
| asyncio | 高并发网络 IO | 链路里混入阻塞库 |
CPython 的 GIL 会让同一进程内多个线程不能同时执行 Python 字节码,所以 CPU 密集任务用多线程通常不会明显变快。但 IO 等待时线程可以让出执行,线程仍适合阻塞 IO。
asyncio 原理
flowchart TD
A["事件循环"] --> B["运行协程 A"]
B --> C{"遇到 await IO"}
C -- "是" --> D["挂起 A"]
D --> E["运行协程 B"]
E --> F["IO 完成后恢复 A"]async 阻塞错误 Demo
错误:
import time
async def bad_api():
time.sleep(3)
return {"ok": True}正确:
import asyncio
async def good_api():
await asyncio.sleep(3)
return {"ok": True}如果必须调用同步阻塞库:
result = await asyncio.to_thread(sync_call)背压
并发不是越大越好。没有背压会把下游接口、数据库连接池、模型服务和内存队列打爆。
import asyncio
sem = asyncio.Semaphore(20)
async def limited_call(client, item_id: int):
async with sem:
return await client.get(f"/items/{item_id}", timeout=3)阶段十:FastAPI Web API
请求链路
flowchart TD
A["客户端请求"] --> B["Uvicorn"]
B --> C["ASGI"]
C --> D["FastAPI 路由匹配"]
D --> E["Pydantic 参数校验"]
E --> F["依赖注入"]
F --> G["执行接口函数"]
G --> H["序列化响应"]
H --> I["返回 HTTP 响应"]最小分层 Demo
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class AssetCreate(BaseModel):
name: str
owner: str
class AssetService:
def create(self, request: AssetCreate) -> dict:
if not request.name.strip():
raise ValueError("资产名称不能为空")
return {"id": 1, "name": request.name, "owner": request.owner}
service = AssetService()
@app.post("/assets")
def create_asset(request: AssetCreate):
try:
return service.create(request)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc生产项目不要把 SQL、外部调用、复杂业务都写在接口函数里,要分 Router、Service、Repository、Schema。
阶段十一:数据库、事务和连接池
关键原则
| 原则 | 原因 |
|---|---|
| 参数化查询 | 防 SQL 注入 |
| 每个请求一个 Session | 避免连接和事务串扰 |
| 事务短小 | 减少锁持有时间 |
| 连接池有限 | 数据库连接是昂贵资源 |
| SQL 要可观测 | 慢 SQL 要能定位 |
SQL 注入对比
错误:
sql = f"select * from user where name = '{name}'"正确:
cursor.execute("select * from user where name = %s", (name,))表名、字段名、排序字段不能用普通参数绑定,要用白名单。
阶段十二:CLI、爬虫和自动化
CLI 工具
import argparse
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True)
parser.add_argument("--output", required=True)
args = parser.parse_args()
print(f"input={args.input}, output={args.output}")
if __name__ == "__main__":
main()商业脚本要有参数、退出码、日志、错误文件和幂等设计,不能只靠手工改代码变量。
爬虫和自动化边界
爬虫要遵守网站规则、访问频率、登录授权和数据合规。自动化脚本要有超时、重试、限速和失败记录。
阶段十三:NumPy、Pandas 和数据处理
数据处理不是“会 Pandas API”,而是建立可信数据流水线。
flowchart TD
A["确认业务口径"] --> B["读取数据"]
B --> C["检查行数、列、编码"]
C --> D["类型转换"]
D --> E["缺失和重复处理"]
E --> F["异常值识别"]
F --> G["业务规则过滤"]
G --> H["分组聚合"]
H --> I["导出结果"]
I --> J["总数、金额、样例对账"]Pandas 清洗 Demo
import pandas as pd
def clean_orders(path: str) -> pd.DataFrame:
df = pd.read_csv(path, dtype={"order_id": str})
df = df.dropna(subset=["order_id"]).copy()
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
df = df[df["amount"].notna()]
df = df.drop_duplicates(subset=["order_id"], keep="last")
return df不要随便把缺失值填 0。缺失金额、金额为 0、退款负数在业务上含义不同。
阶段十四:Python AI 工程
Python 常用于模型 API 调用、文档解析、Embedding、向量检索、RAG、评估脚本和 AI Web 后端。
RAG 完整链路
flowchart TD
A["文档采集"] --> B["解析和清洗"]
B --> C["脱敏和权限元数据"]
C --> D["切分 chunk"]
D --> E["生成 Embedding"]
E --> F["写入向量库"]
G["用户问题"] --> H["权限过滤"]
H --> I["向量检索 + 关键词检索"]
I --> J["重排序"]
J --> K["组装 Prompt"]
K --> L["调用模型"]
L --> M["返回答案和引用"]为什么不能只调模型 API
- 没有检索,模型不知道企业私有数据。
- 没有权限过滤,可能泄露用户无权文档。
- 没有评估,Prompt 一改效果不可控。
- 没有 token 和耗时日志,成本失控。
- 没有引用,用户无法验证答案来源。
Tool Calling 规则
模型只能提出工具调用建议,真实执行必须由后端校验:
- 用户权限。
- 参数白名单。
- 幂等键。
- 风险操作二次确认。
- 审计日志。
商业常用场景
医疗数据采集与资产平台
Python 可以承担:
- 医院导出 CSV/Excel 的清洗脚本。
- 数据质量检查和异常明细输出。
- 批量接口联调工具。
- 资产目录报表统计。
- RAG 评估集生成和自动回归。
- 文档解析、Embedding、向量入库任务。
Web API 服务
FastAPI 适合轻量业务服务、AI 后端、内部工具接口。生产要关注超时、限流、日志、异常、连接池、健康检查。
自动化和运维脚本
批量重命名、文件归档、接口巡检、日志分析、报表生成都适合 Python。但脚本也要工程化:参数、日志、异常、测试、幂等。
生产排查流程
本地能跑服务器不能跑
flowchart TD
A["服务器不能跑"] --> B["检查 python --version"]
B --> C["检查虚拟环境是否激活"]
C --> D["检查依赖版本"]
D --> E["检查环境变量和配置"]
E --> F["检查文件路径和权限"]
F --> G["检查编码和系统差异"]Web 接口变慢
flowchart TD
A["接口变慢"] --> B["查 request_id"]
B --> C["拆接口耗时"]
C --> D["数据库 SQL"]
C --> E["外部接口"]
C --> F["AI 模型调用"]
C --> G["CPU 计算"]
D --> H["EXPLAIN、索引、锁等待"]
E --> I["超时、重试、降级"]
F --> J["token、模型、检索耗时"]async 全站慢
flowchart TD
A["async 全站慢"] --> B["查是否调用 time.sleep"]
B --> C["查同步 requests"]
C --> D["查同步数据库驱动"]
D --> E["查 CPU 计算是否阻塞事件循环"]
E --> F["改异步库或 to_thread"]数据报表对不上
flowchart TD
A["报表对不上"] --> B["原始行数"]
B --> C["读取编码和分隔符"]
C --> D["字段类型转换"]
D --> E["缺失和重复处理"]
E --> F["过滤口径"]
F --> G["groupby 聚合"]
G --> H["总金额和样例对账"]常见坑
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 全局安装依赖 | 项目互相污染 | 每项目虚拟环境 |
| 可变默认参数 | 多次调用共享状态 | 默认用 None |
空 except | 线上错误被吞 | 记录日志并保留上下文 |
| 一次性读大文件 | 内存暴涨 | 流式或分块 |
| async 里阻塞 | 全站变慢 | 异步库或 to_thread |
| 拼接 SQL | SQL 注入 | 参数绑定和白名单 |
| print 当日志 | 无级别无堆栈 | logging |
| 测试只看覆盖率 | 没有有效断言 | 覆盖业务边界 |
| Pandas 随便填 0 | 数据口径错误 | 先理解业务含义 |
| RAG 不做权限过滤 | 敏感文档泄露 | 检索前先过滤权限 |
面试标准回答
Python 应该怎么从零学到生产级
不能只学语法。要先掌握环境和依赖,再学变量、控制流、数据结构、函数模块、面向对象、异常文件、类型标注、日志和测试。进阶要理解线程、进程、asyncio 和 GIL,能写 FastAPI 接口和数据库访问,能做 CLI、数据处理、自动化和 AI 工程。生产项目还要关注配置、日志、测试、性能、超时、幂等和排查。Python 变量的本质
Python 变量本质是名字对对象的引用。赋值不是把值复制进盒子,而是让变量名指向对象。多个变量可以引用同一个可变对象,所以修改 list、dict 这类可变对象时,其他引用也能看到变化。这也是可变默认参数和浅拷贝容易出问题的原因。Python 并发怎么选
IO 密集任务可以用线程池或 asyncio,CPU 密集任务更适合多进程或底层 C 扩展。CPython 有 GIL,同一进程内多个线程通常不能并行执行 Python 字节码,所以 CPU 计算用多线程不一定快。asyncio 适合大量网络 IO,但 async 链路中不能调用阻塞函数,否则会卡住事件循环。FastAPI 一次请求怎么走
请求先到 Uvicorn,Uvicorn 按 ASGI 规范把请求交给 FastAPI。FastAPI 做路由匹配、参数提取、Pydantic 校验、依赖注入,然后执行接口函数。函数返回后,FastAPI 把结果序列化成 JSON,再由 Uvicorn 写回 HTTP 响应。Python 做 RAG 的完整流程
离线阶段解析文档、清洗脱敏、切分 chunk、生成 Embedding、写入向量库;在线阶段先按用户权限限定可检索文档范围,再做向量检索和关键词检索,必要时重排序,组装 Prompt 调模型,最后返回答案和引用。生产还要做评估集、token 成本、耗时、权限、审计和回归测试。学懂验收问题
下面问题答不上来,说明还没有真正学懂:
- 为什么不能把依赖装到全局 Python?
if __name__ == "__main__"解决什么问题?- Python 变量为什么说是对象引用?
- 可变默认参数为什么危险?
- list、tuple、dict、set 分别适合什么?
- 模块和包怎么组织项目?
- 什么时候用 dataclass?
- 为什么不要空
except? - 类型标注为什么运行时默认不强校验?
- logging 比 print 强在哪里?
- GIL 为什么影响 CPU 密集多线程?
- async 函数为什么调用后不一定执行?
- 什么是背压,为什么并发要限流?
- FastAPI 中
def和async def怎么选? - 参数绑定为什么能防 SQL 注入?
- Pandas 报表对不上怎么排查?
- 大文件为什么不能一次性读入?
- Mock 什么时候该用,什么时候会失真?
- RAG 为什么要权限过滤?
- Tool Calling 为什么不能让模型直接执行?
关联知识点跳转
| 主题 | 继续学习 |
|---|---|
| Python 首页 | Python 个人知识库 |
| 生产路线 | Python 从零到生产级掌握 |
| 商业训练 | Python 商业场景训练营 |
| 知识地图 | Python 知识地图 |
| 环境 | 环境与包管理 |
| 基础语法 | 基础语法 |
| 数据结构 | 数据结构 |
| 函数模块 | 函数与模块 |
| 面向对象 | 面向对象 |
| 异常文件 | 异常与文件 |
| 类型标注 | 类型标注 |
| 并发异步 | 并发与异步 |
| Web API | Web API 开发 |
| 数据库 | 数据库访问 |
| 数据处理 | 数据处理 |
| CLI | 命令行工具 |
| 爬虫自动化 | 爬虫与自动化 |
| 日志调试 | 日志与调试 |
| 测试 | 测试 |
| 项目实践 | 项目实践 |
| AI 开发 | Python 与 AI 开发 |
| 面试 | Python 面试题 |
