setuptools打包Python包后无法加载包内config.yaml配置文件
问题根因
你的打包配置没有问题,config.yaml已经被正确安装到包目录,报错来自文件读取的路径逻辑错误:
- 代码中
open("config.yaml", "r")使用的是相对进程运行时工作目录的路径,而非相对于loader.py文件自身所在目录的路径 - 你执行命令时所在的工作目录并不是
site-packages/config_loader/,程序会在你当前执行命令的文件夹下查找config.yaml,自然找不到目标文件。
另外注意:执行模块的命令不需要加.py后缀,正确写法是python3 -m config_loader.loader,后缀多余会让Python把参数识别为文件路径而非模块名,可能引发其他导入异常,但这不是本次文件找不到的核心原因。
可行解决方案
方案1:基于__file__拼接绝对路径(全Python版本兼容)
直接通过当前脚本的内置__file__变量获取自身所在绝对路径,再拼接配置文件名,完全不依赖执行命令时的工作目录。修改loader.py内容如下:
import os import yaml # 获取当前loader.py所在的绝对目录 current_dir = os.path.dirname(os.path.abspath(__file__)) # 拼接得到config.yaml的完整绝对路径 config_path = os.path.join(current_dir, "config.yaml") with open(config_path, "r", encoding="utf-8") as stream: try: print(yaml.safe_load(stream)) except yaml.YAMLError as exc: print(exc)
方案2:使用标准库importlib.resources(Python3.7+ 官方推荐,适配更多打包场景)
Python官方提供了专门用于读取包内静态资源的接口,不需要手动处理路径拼接,在zip打包、冻结打包等特殊场景下也能正常读取资源。
- Python3.9+ 可以直接使用标准库自带实现,无需额外安装依赖:
import yaml from importlib.resources import files with files("config_loader").joinpath("config.yaml").open("r", encoding="utf-8") as stream: try: print(yaml.safe_load(stream)) except yaml.YAMLError as exc: print(exc)
- Python3.7/3.8 可以安装backport兼容包使用:
先执行pip install importlib_resources安装依赖,再修改代码:
import yaml from importlib_resources import open_text with open_text("config_loader", "config.yaml", encoding="utf-8") as stream: try: print(yaml.safe_load(stream)) except yaml.YAMLError as exc: print(exc)
补充说明
你现有setup.py中的package_data配置是正确的,不需要额外修改。如果后续需要打包sdist源码包,只需要在MANIFEST.in中加一行recursive-include config_loader *.yaml即可保证源码包中也包含配置文件,不打源码包的话可以忽略这步。
内容的提问来源于stack exchange,提问作者Pranjal Doshi
相关产品推荐
相关产品推荐

