必须用pdm run python main.py才能加载包,因PDM默认启用PEP 582,依赖装入__pypackages__/3.11/lib,但系统Python的sys.path未包含该路径,需pdm run注入路径。

直接用 pdm run python main.py 才能加载你装的包,否则 python main.py 一定报 ModuleNotFoundError ——这不是环境没配好,是 PEP 582 的路径注入机制根本没触发。
为什么 python main.py 找不到包?
因为 PDM 默认启用 PEP 582 模式,所有依赖都安装到项目根目录下的 __pypackages__/3.11/lib(版本号随你当前 Python 变),但系统 Python 启动时 sys.path 里压根没有这个路径。它不会自动“发现”本地包目录,必须靠 pdm run 这层 wrapper 来提前插入路径。
-
pdm run会把__pypackages__/X.Y/lib插入sys.path[0],优先于全局site-packages - IDE(如 PyCharm)需手动将
__pypackages__/X.Y/lib标记为 Sources Root,并确保解释器指向你pdm init时用的那个 Python 版本 - 写脚本或 CI 时别漏掉
pdm run——比如pdm run pytest、pdm run myscript.py
pdm init 后必须手动补的关键字段
pdm init 生成的 pyproject.toml 是个半成品,不填关键字段会导致后续 pdm add 或 pdm sync 行为异常,尤其在多 Python 版本共存时。
-
requires-python = ">=3.9":必须显式声明,否则 PDM 无法判断该用哪个__pypackages__/X.Y子目录 -
dependencies和dev-dependencies建议留空,用pdm add flask/pdm add pytest --group dev自动生成,避免手误格式错误 - 若项目要打包发布,补上
[project]下的name、version、readme等 PEP 621 字段,否则pdm build会警告
pdm add 和 pdm install 的区别在哪?
这两个命令表面相似,但触发逻辑和适用场景完全不同,混用容易导致锁文件过期或依赖不一致。
立即学习“Python免费学习笔记(深入)”;
-
pdm add flask:仅修改pyproject.toml中的dependencies,然后立即解析并安装最新兼容版本到__pypackages__,同时更新pdm.lock -
pdm install:只读取现有pdm.lock,精确还原所有包(含间接依赖)到当前__pypackages__,不碰pyproject.toml,适合 CI 或团队协作时确保环境一致 - 开发中新增依赖,用
pdm add;部署或重装项目,用pdm install;想强制重算依赖树,先删pdm.lock再pdm install
国内镜像源和缓存怎么配才不踩坑?
PDM 默认走官方 PyPI,国内用户不配镜像会卡在下载阶段;而中心化缓存默认开启,但路径不在项目内,容易被误删或权限干扰。
- 设镜像源:
pdm config pypi.url https://pypi.tuna.tsinghua.edu.cn/simple/(清华源)或https://pypi.douban.com/simple/(豆瓣源) - 缓存路径默认在
~/.cache/pdm,可通过pdm config cache_dir /path/to/cache改;不要设成项目内路径,否则git clean -fdx会清掉 - 如果遇到
ConnectionError或下载超时,先pdm config --local pypi.url ...设项目级镜像,避免影响其他 PDM 项目
最常被忽略的是:PEP 582 不是“自动生效”的魔法,它依赖 pdm run 的路径注入、requires-python 的版本锚定、以及 pdm.lock 对间接依赖的锁定——三者缺一不可。少配一个,就可能在另一台机器上跑不通。


















