Wheel包安装后无法找到包内静态资源的原因排查
问题根源分析
核心问题是你硬编码了基于项目根目录的相对路径来读取静态文件,而打包安装后,程序的运行上下文和目录结构已经发生了本质变化:
- 本地通过
poetry run execute-script运行时,脚本的工作目录是你的项目根目录,此时src/static/mapping.json这个相对路径能正确指向项目里的文件。 - 当用
poetry build生成wheel并安装后,你的项目内容会被部署到Python的site-packages目录下,此时:- 脚本的工作目录不再是原项目根目录,原相对路径自然失效;
- Poetry打包时不会保留原项目的
src目录结构——它会把src下的包内容直接放到site-packages根目录(或对应包名的子目录),所以site-packages里根本不存在src/static/mapping.json这个路径(你看到的文件实际路径应该是site-packages/static/mapping.json或site-packages/cmd_tool/static/mapping.json,取决于你的项目结构)。
哪怕文件确实被打包到了site-packages,硬编码的固定路径也无法适配安装后的动态位置。
解决思路
不要用固定相对路径读取资源,改用Python标准库的importlib.resources(Python 3.9+)来获取包内资源:
- 假设你的静态文件在
src/cmd_tool/static/mapping.json(符合Poetry标准包结构),可以这样读取:
from importlib.resources import files # 获取资源路径 mapping_path = files("cmd_tool").joinpath("static/mapping.json") # 读取文件内容 with open(mapping_path, "r") as f: data = f.read()
如果你的项目结构是src/static/直接在src根下,需要先在pyproject.toml里配置Poetry把static目录包含到包中:
[tool.poetry] packages = [ { include = "static", from = "src" } ]
然后同样用importlib.resources从对应路径读取资源。
内容的提问来源于stack exchange,提问作者lapots
相关产品推荐
相关产品推荐

