1. 课程导入与工程全景

很多 Python 项目在开发者本机运行良好,一旦交付给同事、部署到服务器或发布到 PyPI,就会立刻暴露出一连串问题:ModuleNotFoundError、版本冲突、编译失败、环境不一致、安装后缺少数据文件。这些现象背后并不是 Python 语言本身的问题,而是打包与依赖管理这一工程环节没有被系统处理。本课程要解决的,正是从"能跑"到"可交付、可复现、可发布"之间的这段工程距离。

一、两个核心问题:打包与依赖

先明确两个概念。所谓打包(packaging),是把源码、包结构、元数据、资源文件、入口脚本组织成一个可被安装、可被分发的构件,常见形态是 wheel(.whl)和源码分发包(.tar.gz)。所谓依赖管理(dependency management),是声明项目需要哪些第三方库、允许什么版本范围,并把这些约束解析成一组确定、可复现的安装集合。

两者是耦合的:打包产物的元数据里必须写清依赖声明,否则安装者拿到的 wheel 无法自动拉取正确依赖;而依赖解析的结果又必须能被锁定和复现,否则今天装得上、明天装不上。理解这一点,就能理解为什么本课程不把二者拆开讲。

核心判断:一个 Python 项目是否"工程化",看三件事——别人能否一条命令装上、装上的版本是否与你一致、装完后能否直接调用入口。

二、典型痛点:从现场故障反推工程缺口

下面这些场景在真实项目中反复出现,它们分别指向不同的工程缺口。

  • 依赖漂移:requirements.txt 里只写 requests,没有版本约束。今天解析到 2.31,半年后解析到 2.32,行为差异导致线上报错。缺口在于缺少锁定文件与版本策略。
  • 环境不一致:开发用 Python 3.11,服务器是 3.8,代码里用了 match 语句或新类型语法,部署即失败。缺口在于缺少 requires-python 声明与 CI 多版本验证。
  • 隐式依赖:本机恰好装过 numpy,代码直接 import,但项目元数据里没写。换台干净机器就崩。缺口在于依赖声明不完整。
  • 包结构错误:源码放在 src/ 下但没配 package-dir,或者缺少 __init__.py,导致 pip install . 后 import 不到子包。缺口在于构建后端配置。
  • 资源文件丢失:模板、配置、模型权重放在包目录里,但没在打包配置中声明,wheel 里根本没有这些文件。缺口在于数据文件包含规则。
  • 依赖冲突:A 库要求 urllib3<2,B 库要求 urllib3>=2,解析器报 ResolutionImpossible。缺口在于缺少冲突定位与版本协商能力。

把这些痛点归位,可以看到它们分别落在项目结构、元数据声明、依赖解析、构建产物、发布分发、环境复现六个环节上。本课程的学习路径正是沿这六个环节展开。

三、工具生态全景

Python 打包生态经历过多次演进,今天的主流格局可以按职责分层理解。

层次代表工具职责
构建后端setuptools、hatchling、flit、pdm-backend把源码构建成 wheel/sdist,读取 pyproject.toml
构建前端build、pip wheel调用后端,产出构件
依赖与环境pip + venv、pip-tools、Poetry、PDM、uv、Conda解析、锁定、安装依赖,管理虚拟环境
发布分发twine、PyPI、私有索引(devpi、Artifactory)上传构件、托管索引
质量与验证pytest、tox、nox、GitHub Actions多环境测试、CI 自动构建发布

需要强调的是:这些工具不是互斥的替代关系,而是可以组合的。一个常见组合是 pyproject.toml + hatchling 负责构建,uv 或 pip-tools 负责锁定,twine 负责上传,GitHub Actions 负责串联。课程后续会逐一展开,但先建立这张全景图,避免陷入"工具选型焦虑"。

四、一张图看清工程链路

下图把从源码到可安装构件的完整链路、每段链路的输入输出、以及对应的工具与常见故障点放在一起,作为本课程的总览地图。

Python 项目打包与依赖管理工程链路 源码 → 元数据 → 依赖解析 → 构建 → 构件 → 发布 → 安装复现 项目源码 src/ 包结构 __init__.py 元数据声明 pyproject.toml name/version/deps 依赖解析 版本约束求解 lock 锁定 构建构件 wheel / sdist build 后端 发布与安装 PyPI / 私有索引 pip install 工具层 setuptools / hatchling pip / venv / uv Poetry / PDM / pip-tools build / twine tox / nox / GitHub Actions 常见故障点(对应链路位置) 包结构错误 / 缺 __init__.py 依赖声明不完整(隐式依赖) 版本冲突 ResolutionImpossible 资源文件未包含 / 入口点缺失 requires-python 未声明 依赖漂移(无 lock 文件) 构建后端配置错误 上传到错误索引 / 版本重复 工程闭环 干净环境安装验证 → 多 Python 版本测试 → 锁定文件提交 → CI 自动构建 → 发布前检查元数据 → 安装后 import 与入口自检 判断标准:在全新虚拟环境中执行 pip install <构件> 后,无需手工补装任何包即可成功 import 并运行入口命令。

五、学习路径与本节定位

基于上面的链路,本课程的学习路径按"先能装、再能锁、后能发"推进:

  1. 项目结构与元数据:理解 pyproject.toml 的字段含义,掌握 src 布局与包发现规则。
  2. 依赖声明与锁定:区分直接依赖与传递依赖,掌握版本约束语法与 lock 文件的作用。
  3. 构建与产物检查:用 python -m build 产出 wheel,解压检查内容是否完整。
  4. 发布与私有索引:用 twine 上传,理解 PyPI 与私有源的差异。
  5. 环境复现与 CI:在干净环境验证安装,用 CI 固化流程。