Skip to content

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
生产排查能按日志、异常、性能、依赖、数据口径定位出错只重跑脚本

总学习路线

mermaid
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 程序运行依赖三个层次:

  1. Python 解释器:负责执行 .py 文件。
  2. 虚拟环境:隔离项目依赖。
  3. 依赖清单:记录项目需要哪些第三方库。
mermaid
flowchart TD
    A["python 命令"] --> B["解释器版本"]
    B --> C["虚拟环境 .venv"]
    C --> D["安装依赖"]
    D --> E["运行项目代码"]

为什么需要虚拟环境

如果把依赖都装到全局环境:

  1. A 项目升级 pandas 可能导致 B 项目报错。
  2. 本地和服务器依赖版本不一致。
  3. 不知道项目到底依赖哪些包。
  4. 删除或迁移项目时很难清理。

Demo:标准环境准备

bash
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 文件时,会按从上到下的顺序执行顶层语句。函数定义本身只是创建函数对象,函数体不会立即执行,直到被调用。

mermaid
flowchart TD
    A["python app.py"] --> B["启动解释器"]
    B --> C["读取文件"]
    C --> D["解析语法"]
    D --> E["执行顶层语句"]
    E --> F["遇到函数定义创建函数对象"]
    F --> G["调用 main 才执行函数体"]

程序入口 Demo

python
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 变量本质是名字绑定对象,不是把值装进固定盒子。

mermaid
flowchart TD
    A["变量 a"] --> C["列表对象 [1,2]"]
    B["变量 b"] --> C
    C --> D["b.append(3)"]
    D --> E["a 也能看到变化"]

可变对象坑 Demo

python
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"],因为默认参数只在函数定义时创建一次。正确写法:

python
def add_item(item: str, bucket: list[str] | None = None) -> list[str]:
    if bucket is None:
        bucket = []
    bucket.append(item)
    return bucket

不理解会怎样

问题后果
不懂引用修改一个列表影响另一个变量
不懂可变默认参数多次调用互相污染
不懂浅拷贝嵌套对象仍共享
不懂类型转换用户输入字符串参与数字计算报错

阶段四:数据结构选择

结构特点适合
list有序、可变、可重复结果列表、批量数据
tuple有序、不可变固定返回值、坐标、只读结构
dictkey-value 映射按 ID 查对象、配置、索引
set去重、集合运算去重、交并差

Demo:用 dict 建索引

python
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 文件,包负责把多个模块组织成目录。

mermaid
flowchart TD
    A["项目"] --> B["api 模块"]
    A --> C["service 模块"]
    A --> D["repository 模块"]
    A --> E["utils 模块"]
    C --> D
    B --> C

不拆模块会怎样

  1. 一个文件几千行,定位困难。
  2. 函数互相依赖,无法单测。
  3. Web、数据库、业务规则混在一起。
  4. 改一个小需求影响全文件。

推荐分层

text
app/
  api/
  services/
  repositories/
  schemas/
  models/
  core/
tests/

阶段六:面向对象和数据建模

Python 面向对象不是为了“所有代码都写成类”,而是当数据和行为需要放在一起表达时使用。

dataclass Demo

python
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.count

frozen=True 让对象不可变,适合表达导入后的明细、配置快照、值对象。

继承和组合

继承适合明确的“is-a”关系;组合适合“has-a”关系。商业项目里很多场景组合比继承更稳。

python
class CsvParser:
    def parse(self, path: str) -> list[dict]:
        ...


class ImportService:
    def __init__(self, parser: CsvParser):
        self.parser = parser

阶段七:异常、文件和资源管理

异常不是错误的敌人,而是错误的表达方式。好的异常处理要保留上下文,不要吞掉问题。

文件读取 Demo

python
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() 全部内容,可以逐行或分块处理。

python
def count_lines(path: str) -> int:
    count = 0
    with open(path, "r", encoding="utf-8") as f:
        for _ in f:
            count += 1
    return count

阶段八:类型标注、日志和测试

类型标注

类型标注是函数契约,不是运行时强制检查。

python
def normalize_phone(phone: str) -> str:
    return phone.strip().replace(" ", "")

它的价值:

  1. 让调用方知道传什么、返回什么。
  2. IDE 能提示。
  3. 静态检查工具能提前发现错误。
  4. 大项目重构更安全。

logging

python
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_idbatch_id、耗时、错误码和关键业务 ID。

pytest Demo

python
def normalize_status(status: str) -> str:
    mapping = {"启用": "ENABLED", "停用": "DISABLED"}
    if status not in mapping:
        raise ValueError(f"未知状态: {status}")
    return mapping[status]
python
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 原理

mermaid
flowchart TD
    A["事件循环"] --> B["运行协程 A"]
    B --> C{"遇到 await IO"}
    C -- "是" --> D["挂起 A"]
    D --> E["运行协程 B"]
    E --> F["IO 完成后恢复 A"]

async 阻塞错误 Demo

错误:

python
import time


async def bad_api():
    time.sleep(3)
    return {"ok": True}

正确:

python
import asyncio


async def good_api():
    await asyncio.sleep(3)
    return {"ok": True}

如果必须调用同步阻塞库:

python
result = await asyncio.to_thread(sync_call)

背压

并发不是越大越好。没有背压会把下游接口、数据库连接池、模型服务和内存队列打爆。

python
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

请求链路

mermaid
flowchart TD
    A["客户端请求"] --> B["Uvicorn"]
    B --> C["ASGI"]
    C --> D["FastAPI 路由匹配"]
    D --> E["Pydantic 参数校验"]
    E --> F["依赖注入"]
    F --> G["执行接口函数"]
    G --> H["序列化响应"]
    H --> I["返回 HTTP 响应"]

最小分层 Demo

python
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 注入对比

错误:

python
sql = f"select * from user where name = '{name}'"

正确:

python
cursor.execute("select * from user where name = %s", (name,))

表名、字段名、排序字段不能用普通参数绑定,要用白名单。

阶段十二:CLI、爬虫和自动化

CLI 工具

python
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”,而是建立可信数据流水线。

mermaid
flowchart TD
    A["确认业务口径"] --> B["读取数据"]
    B --> C["检查行数、列、编码"]
    C --> D["类型转换"]
    D --> E["缺失和重复处理"]
    E --> F["异常值识别"]
    F --> G["业务规则过滤"]
    G --> H["分组聚合"]
    H --> I["导出结果"]
    I --> J["总数、金额、样例对账"]

Pandas 清洗 Demo

python
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 完整链路

mermaid
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

  1. 没有检索,模型不知道企业私有数据。
  2. 没有权限过滤,可能泄露用户无权文档。
  3. 没有评估,Prompt 一改效果不可控。
  4. 没有 token 和耗时日志,成本失控。
  5. 没有引用,用户无法验证答案来源。

Tool Calling 规则

模型只能提出工具调用建议,真实执行必须由后端校验:

  1. 用户权限。
  2. 参数白名单。
  3. 幂等键。
  4. 风险操作二次确认。
  5. 审计日志。

商业常用场景

医疗数据采集与资产平台

Python 可以承担:

  1. 医院导出 CSV/Excel 的清洗脚本。
  2. 数据质量检查和异常明细输出。
  3. 批量接口联调工具。
  4. 资产目录报表统计。
  5. RAG 评估集生成和自动回归。
  6. 文档解析、Embedding、向量入库任务。

Web API 服务

FastAPI 适合轻量业务服务、AI 后端、内部工具接口。生产要关注超时、限流、日志、异常、连接池、健康检查。

自动化和运维脚本

批量重命名、文件归档、接口巡检、日志分析、报表生成都适合 Python。但脚本也要工程化:参数、日志、异常、测试、幂等。

生产排查流程

本地能跑服务器不能跑

mermaid
flowchart TD
    A["服务器不能跑"] --> B["检查 python --version"]
    B --> C["检查虚拟环境是否激活"]
    C --> D["检查依赖版本"]
    D --> E["检查环境变量和配置"]
    E --> F["检查文件路径和权限"]
    F --> G["检查编码和系统差异"]

Web 接口变慢

mermaid
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 全站慢

mermaid
flowchart TD
    A["async 全站慢"] --> B["查是否调用 time.sleep"]
    B --> C["查同步 requests"]
    C --> D["查同步数据库驱动"]
    D --> E["查 CPU 计算是否阻塞事件循环"]
    E --> F["改异步库或 to_thread"]

数据报表对不上

mermaid
flowchart TD
    A["报表对不上"] --> B["原始行数"]
    B --> C["读取编码和分隔符"]
    C --> D["字段类型转换"]
    D --> E["缺失和重复处理"]
    E --> F["过滤口径"]
    F --> G["groupby 聚合"]
    G --> H["总金额和样例对账"]

常见坑

后果正确做法
全局安装依赖项目互相污染每项目虚拟环境
可变默认参数多次调用共享状态默认用 None
except线上错误被吞记录日志并保留上下文
一次性读大文件内存暴涨流式或分块
async 里阻塞全站变慢异步库或 to_thread
拼接 SQLSQL 注入参数绑定和白名单
print 当日志无级别无堆栈logging
测试只看覆盖率没有有效断言覆盖业务边界
Pandas 随便填 0数据口径错误先理解业务含义
RAG 不做权限过滤敏感文档泄露检索前先过滤权限

面试标准回答

Python 应该怎么从零学到生产级

text
不能只学语法。要先掌握环境和依赖,再学变量、控制流、数据结构、函数模块、面向对象、异常文件、类型标注、日志和测试。进阶要理解线程、进程、asyncio 和 GIL,能写 FastAPI 接口和数据库访问,能做 CLI、数据处理、自动化和 AI 工程。生产项目还要关注配置、日志、测试、性能、超时、幂等和排查。

Python 变量的本质

text
Python 变量本质是名字对对象的引用。赋值不是把值复制进盒子,而是让变量名指向对象。多个变量可以引用同一个可变对象,所以修改 list、dict 这类可变对象时,其他引用也能看到变化。这也是可变默认参数和浅拷贝容易出问题的原因。

Python 并发怎么选

text
IO 密集任务可以用线程池或 asyncio,CPU 密集任务更适合多进程或底层 C 扩展。CPython 有 GIL,同一进程内多个线程通常不能并行执行 Python 字节码,所以 CPU 计算用多线程不一定快。asyncio 适合大量网络 IO,但 async 链路中不能调用阻塞函数,否则会卡住事件循环。

FastAPI 一次请求怎么走

text
请求先到 Uvicorn,Uvicorn 按 ASGI 规范把请求交给 FastAPI。FastAPI 做路由匹配、参数提取、Pydantic 校验、依赖注入,然后执行接口函数。函数返回后,FastAPI 把结果序列化成 JSON,再由 Uvicorn 写回 HTTP 响应。

Python 做 RAG 的完整流程

text
离线阶段解析文档、清洗脱敏、切分 chunk、生成 Embedding、写入向量库;在线阶段先按用户权限限定可检索文档范围,再做向量检索和关键词检索,必要时重排序,组装 Prompt 调模型,最后返回答案和引用。生产还要做评估集、token 成本、耗时、权限、审计和回归测试。

学懂验收问题

下面问题答不上来,说明还没有真正学懂:

  1. 为什么不能把依赖装到全局 Python?
  2. if __name__ == "__main__" 解决什么问题?
  3. Python 变量为什么说是对象引用?
  4. 可变默认参数为什么危险?
  5. list、tuple、dict、set 分别适合什么?
  6. 模块和包怎么组织项目?
  7. 什么时候用 dataclass?
  8. 为什么不要空 except
  9. 类型标注为什么运行时默认不强校验?
  10. logging 比 print 强在哪里?
  11. GIL 为什么影响 CPU 密集多线程?
  12. async 函数为什么调用后不一定执行?
  13. 什么是背压,为什么并发要限流?
  14. FastAPI 中 defasync def 怎么选?
  15. 参数绑定为什么能防 SQL 注入?
  16. Pandas 报表对不上怎么排查?
  17. 大文件为什么不能一次性读入?
  18. Mock 什么时候该用,什么时候会失真?
  19. RAG 为什么要权限过滤?
  20. Tool Calling 为什么不能让模型直接执行?

关联知识点跳转

主题继续学习
Python 首页Python 个人知识库
生产路线Python 从零到生产级掌握
商业训练Python 商业场景训练营
知识地图Python 知识地图
环境环境与包管理
基础语法基础语法
数据结构数据结构
函数模块函数与模块
面向对象面向对象
异常文件异常与文件
类型标注类型标注
并发异步并发与异步
Web APIWeb API 开发
数据库数据库访问
数据处理数据处理
CLI命令行工具
爬虫自动化爬虫与自动化
日志调试日志与调试
测试测试
项目实践项目实践
AI 开发Python 与 AI 开发
面试Python 面试题