手动建包目录易出错,cookiecutter可一键生成符合pep 517/518、src/布局、pyproject.toml、测试目录及type stubs等现代规范的可发布结构,避免import失败、pip install -e .报错等问题。

为什么不用手动建包目录,而要用 Cookiecutter
手动创建符合 pyproject.toml、src/ 布局、测试目录、type stubs 等标准的 Python 包结构,容易漏掉 __init__.py 位置、搞错 packages 发布配置、或把测试文件混进源码里。Cookiecutter 本质是模板填充工具,它不运行代码,只按变量替换生成静态文件树——这意味着你拿到的是“已验证过可发布的结构”,不是靠文档脑补出来的。
常见错误现象:pip install -e . 失败、import mypkg 报 ModuleNotFoundError、CI 上 pytest 找不到测试——八成源于初始结构没对齐现代打包规范(PEP 517/518 + setuptools 或 hatch)。
选哪个 Cookiecutter 模板最稳妥
推荐用 audreyr/cookiecutter-pypackage(维护活跃、支持 src/ 布局和 pyproject.toml),避免用已归档的旧模板(如 cookiecutter-pypackage-minimal)。注意它默认生成的是 setup.py + setup.cfg 混合结构,你需要主动选 use_pyproject 为 y,否则会退回旧式打包流程。
执行命令时关键参数:
cookiecutter https://github.com/audreyr/cookiecutter-pypackage- 遇到
use_pyproject [n]:→ 输y - 遇到
use_src_layout [y]:→ 输y(强制src/mypkg/,避免 import 冲突) - 遇到
command_line_interface [no]:→ 按需输click或留空
生成后立刻检查根目录是否存在 pyproject.toml,且里面包含 [build-system] 和 [project] 段——没有就说明模板没走对路径。
生成后必须改的三处配置
Cookiecutter 只填骨架,不替你写业务逻辑,但以下三处不改,包根本跑不起来:
-
pyproject.toml中的project.name必须和src/下实际包名一致(比如project.name = "mycoolpkg"→ 目录必须是src/mycoolpkg/) -
src/mycoolpkg/__init__.py至少要有一行__version__ = "0.1.0",否则importlib.metadata.version("mycoolpkg")会炸 -
tests/下的conftest.py如果存在,确认它没硬编码sys.path.insert(0, "..")——src/布局下 pytest 默认能发现包,加这个反而导致导入重复
验证方式:在项目根目录运行 python -m build,成功输出 dist/mypkg-0.1.0-py3-none-any.whl;再用 pip install dist/*.whl,然后 python -c "import mycoolpkg; print(mycoolpkg.__version__)" 能打印版本即通过。
为什么 src/ 布局比平铺更安全
新手常把模块直接放项目根目录(mycoolpkg.py),结果 pytest 在根目录跑时会把当前路径加入 sys.path,导致 import 的是本地文件而非已安装包,掩盖了 import 路径 bug。而 src/ 布局强制所有代码在 src/ 下,配合 pyproject.toml 中 packages = [{include = "mycoolpkg", from = "src"}],让构建工具和 IDE 都明确知道“源码在哪、发布什么”。
性能影响几乎为零,但兼容性上要注意:某些老 CI 脚本(比如硬写 python setup.py test)会失效,必须改用 pytest --pyargs mycoolpkg 或 python -m pytest tests/。
真正容易被忽略的是:PyCharm 默认不把 src/ 标为 Sources Root,得右键目录 → Mark Directory as → Sources Root,否则类型提示和跳转会断。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











