You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Python Egg打包后无法访问内置非代码文件的技术咨询

解决Python Egg包中无法访问数据文件的问题

为啥会踩这个坑?

当代码打包成egg格式后,整个包会变成一个压缩归档文件——里面的资源文件不再是操作系统文件系统里的独立文件。你原来靠os.path基于脚本路径找DataBank子目录的方法自然就失效了,毕竟这些文件现在藏在压缩包内部,不是真实的文件系统路径。

一步步解决问题

1. 先确保打包时把数据文件带进去

首先得修改你的打包配置(一般是setup.py),明确告诉setuptools要把这三个数据文件塞进egg包。因为DataBankWordProject.Repository包的子目录,用package_data声明最靠谱:

setup.py里加这段配置:

from setuptools import setup, find_packages

setup(
    name="WordProject",
    version="1.0",
    packages=find_packages(),
    package_data={
        # 给WordProject.Repository包指定要包含的资源文件
        "WordProject.Repository": ["DataBank/*.csv", "DataBank/*.txt"],
    },
)

这样打包时,setuptools就会自动把DataBank下的三个文件都包含进egg包了。

2. 改代码用pkg_resources访问资源

接下来要调整RepositoryReader里读取文件的逻辑,别再用os.path了,换成setuptools自带的pkg_resources模块——它专门处理Python包内的资源,不管是在本地文件系统还是压缩包(egg/wheel)里都能正常工作。

比如你原来的代码可能是这样:

import os

class RepositoryReader:
    def __init__(self):
        data_dir = os.path.join(os.path.dirname(__file__), "DataBank")
        self.synonyms_path = os.path.join(data_dir, "synonyms.csv")
        # 其他文件路径处理...

现在改成用pkg_resources

import pkg_resources

class RepositoryReader:
    def __init__(self):
        # 获取synonyms.csv的可用路径(如果是egg包,会临时提取到缓存目录)
        self.synonyms_path = pkg_resources.resource_filename(
            __name__, "DataBank/synonyms.csv"
        )
        # 更高效的方式:直接获取文件流,不用纠结路径
        with pkg_resources.resource_stream(__name__, "DataBank/acronyms.csv") as f:
            acronyms_content = f.read().decode("utf-8")
        # 同理处理words.txt...
  • pkg_resources.resource_filename会返回一个可直接使用的文件路径——如果是egg包,它会自动把文件临时提取到系统缓存目录,再返回这个临时路径。
  • pkg_resources.resource_stream更省事,直接返回文件流,适合直接读取内容的场景,不用管文件实际存在哪儿。

3. 重新打包测试

改完配置和代码后,重新跑打包命令生成egg包:

python setup.py bdist_egg

安装这个新的egg包,再测试RepositoryReader就能正常访问那三个数据文件了。

额外小提示

如果你的项目已经在用现代的pyproject.toml(更推荐这种方式),也可以用下面的配置代替setup.py里的package_data

[tool.setuptools.package-data]
"WordProject.Repository" = ["DataBank/*.csv", "DataBank/*.txt"]

内容的提问来源于stack exchange,提问作者iam.Carrot

火山引擎 最新活动