我使用setuptools分发我的python包。现在,我需要分发其他数据文件。
从setuptools文档中收集的信息来看,我需要将数据文件保存在package目录中。但是,我宁愿将数据文件放在根目录的子目录中。
我要避免的是:
/ #root |- src/ | |- mypackage/ | | |- data/ | | | |- resource1 | | | |- [...] | | |- __init__.py | | |- [...] |- setup.py
我想拥有的是:
/ #root |- data/ | |- resource1 | |- [...] |- src/ | |- mypackage/ | | |- __init__.py | | |- [...] |- setup.py
如果不是必须的,我只是对拥有这么多子目录感到不满意。我找不到原因,为什么我必须将文件放在包目录中。使用如此众多的嵌套子目录恕我直言也很麻烦。还是有什么充分的理由可以证明这一限制?
选项1:作为软件包数据安装
将数据文件放置在Python包的根目录中的主要优点是,它使您避免担心文件在用户系统上的位置,这些系统可能是Windows,Mac,Linux,某些移动平台或Egg内。data无论安装在何处或如何安装,始终可以找到相对于Python软件包根目录的目录。
data
例如,如果我有这样的项目布局:
project/ foo/ __init__.py data/ resource1/ foo.txt
您可以添加一个函数来__init__.py定位数据文件的绝对路径:
__init__.py
import os _ROOT = os.path.abspath(os.path.dirname(__file__)) def get_data(path): return os.path.join(_ROOT, 'data', path) print get_data('resource1/foo.txt')
输出:
/Users/pat/project/foo/data/resource1/foo.txt
在将项目安装为Egg以后,data将更改路径,但是不需要更改代码:
/Users/pat/virtenv/foo/lib/python2.6/site-packages/foo-0.0.0-py2.6.egg/foo/data/resource1/foo.txt
选项2:安装到固定位置
另一种方法是将您的数据放在Python包之外,然后执行以下任一操作:
如果您打算分发您的项目,那么这是远远不够的。如果 确实 要执行此操作,则可以data通过传入元组列表来指定每组文件的目标位置,从而将其安装在目标系统上的任意位置:
from setuptools import setup setup( ... data_files=[ ('/var/data1', ['data/foo.txt']), ('/var/data2', ['data/bar.txt']) ] )
更新 :递归grep Python文件的shell函数示例:
atlas% function grep_py { find . -name '*.py' -exec grep -Hn $* {} \; } atlas% grep_py ": \[" ./setup.py:9: package_data={'foo': ['data/resource1/foo.txt']}