如何在Python egg中分发/访问数据文件?
我正在写一个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
。
这让我有两个问题:
- 我是否应该使用其他方法来查找数据文件,无论是使用egg安装还是传统的系统安装?如果是的话,应该用什么呢?
- 我是否应该以不同的方式分发我的数据文件,以便在egg中更容易找到它们?
我知道pkgutil.get_data
这个方法,但我不想使用它。我对这些数据文件的内容不感兴趣,我想知道它们的位置,这样我才能执行它们。
我目前的计划是这样做:
- 使用
package_data
来代替data_files
- 修改pkgme,使其相对于
pkgme.__file__
来查找后端,而不是sys.prefix
2 个回答
你现在的计划基本上是对的,或者说是一个可行的选择。
当setuptools创建一个egg文件时,它会检查这个egg里的代码是否使用了__file__
。如果使用了,它就会标记这个egg不能以压缩的形式安装。这样一来,当你用easy_install安装这个egg时,它会被解压到一个.egg/
目录里,而不是直接放在一个.egg
文件里。
如果你想支持压缩的“直接放入”安装方式(也就是把egg文件直接放到一个目录里,而不进行真正的“安装”),那么你应该使用pkg_resources.resource_filename()
这个API,而不是__file__
。不过这样的话,你的包就需要依赖setuptools或者distribute,才能使用这个API。
我最后做了以下几件事:
- 把pkgme改成使用
pkg_resources.resource_filename()
来找到它自己包含的后端 - 增加了一个入口点,任何用Python写的后端都可以用来发布自己后端脚本的位置
- 保留了基于
sys.prefix
的检查,以便那些不想使用Python的后端也能工作
具体的改动可以在这里找到:http://bazaar.launchpad.net/~pkgme-committers/pkgme/trunk/revision/86