如何在Python egg中分发/访问数据文件?

3 投票
2 回答
3077 浏览
提问于 2025-04-17 06:21

我正在写一个Django应用程序,使用pip和virtualenv来管理开发环境。

其中一个依赖项是pkgme,它带有很多数据文件,这些文件被称为“后端”,并在它的setup.py文件中用data_files=$FOO来配置(而不是用package_data)。

当pkgme寻找它的后端时,它会在os.path.join(sys.prefix, "share", "pkgme", "backends")这个路径下查找。这样做在pkgme正常安装时效果很好,看起来也符合文档的说明,但当pkgme作为egg安装时,这种方法就不管用了。

在egg安装的情况下,数据文件会被放在$VIRTUAL_ENV/lib/python2.7/site-packages/pkgme-0.1-py2.7.egg/share这个路径下,而不是我们预期的$VIRTUAL_ENV/share

这让我有两个问题:

  1. 我是否应该使用其他方法来查找数据文件,无论是使用egg安装还是传统的系统安装?如果是的话,应该用什么呢?
  2. 我是否应该以不同的方式分发我的数据文件,以便在egg中更容易找到它们?

我知道pkgutil.get_data这个方法,但我不想使用它。我对这些数据文件的内容不感兴趣,我想知道它们的位置,这样我才能执行它们。

我目前的计划是这样做:

  • 使用package_data来代替data_files
  • 修改pkgme,使其相对于pkgme.__file__来查找后端,而不是sys.prefix

2 个回答

2

你现在的计划基本上是对的,或者说是一个可行的选择。

当setuptools创建一个egg文件时,它会检查这个egg里的代码是否使用了__file__。如果使用了,它就会标记这个egg不能以压缩的形式安装。这样一来,当你用easy_install安装这个egg时,它会被解压到一个.egg/目录里,而不是直接放在一个.egg文件里。

如果你想支持压缩的“直接放入”安装方式(也就是把egg文件直接放到一个目录里,而不进行真正的“安装”),那么你应该使用pkg_resources.resource_filename()这个API,而不是__file__。不过这样的话,你的包就需要依赖setuptools或者distribute,才能使用这个API。

1

我最后做了以下几件事:

  • 把pkgme改成使用pkg_resources.resource_filename()来找到它自己包含的后端
  • 增加了一个入口点,任何用Python写的后端都可以用来发布自己后端脚本的位置
  • 保留了基于sys.prefix的检查,以便那些不想使用Python的后端也能工作

具体的改动可以在这里找到:http://bazaar.launchpad.net/~pkgme-committers/pkgme/trunk/revision/86

撰写回答