我编写了一个Python包,其中包含一个bsddb数据库,其中包含一个更耗时的计算的预先计算值。为简单起见,我的安装脚本将数据库文件安装在与访问数据库的代码相同的目录中(在Unix上,类似于/usr/lib/python2.5/site-packages/mypackage /)。
如何存储数据库文件的最终位置,以便我的代码可以访问它?现在,我正在使用基于访问数据库的模块中__file__
变量的hack:
dbname = os.path.join(os.path.dirname(__file__), "database.dat")
它有效,但看起来......是hackish。有一个更好的方法吗?我想让安装脚本从distutils模块中获取最终安装位置,并将其填入“dbconfig.py”文件中,该文件与访问数据库的代码一起安装。
答案 0 :(得分:29)
尝试使用pkg_resources,它是setuptools的一部分(在我现在可以访问的所有pythons上都可用):
>>> import pkg_resources
>>> pkg_resources.resource_ filename(__name__, "foo.config")
'foo.config'
>>> pkg_resources.resource_filename('tempfile', "foo.config")
'/usr/lib/python2.4/foo.config'
有关使用pkg_resources获取eggs页面和pkg_resources页面上资源的更多讨论。
另请注意,在可能的情况下,建议使用pkg_resources.resource_stream或pkg_resources.resource_string,因为如果包是egg的一部分,resource_filename会将文件复制到临时目录。
答案 1 :(得分:16)
使用pkgutil.get_data
。它是pkg_resources.resource_stream
的表亲,但在标准库中,应该使用平面文件系统安装以及压缩包和其他导入程序。
答案 2 :(得分:4)
这可能就是这样做的方式,而不需要使用更高级的东西,比如使用setuptools来安装它们所属的文件。
请注意,该方法存在问题,因为在具有真实安全框架(UNIX等)的操作系统上,运行脚本的用户可能无权访问安装它的系统目录中的数据库。
答案 3 :(得分:0)
使用标准的Python-3.7库的importlib.resources
module,
比more efficient setuptools:pkg_resources
(在以前的Python版本中,请使用向后移植的importlib_resources
library)。
注意:要使其正常工作,数据文件所在的文件夹必须是常规的python-package 。这意味着您必须在其中添加一个__init__.py
文件。
然后您可以像这样访问它:
try:
import importlib.resources as importlib_resources
except ImportError:
# In PY<3.7 fall-back to backported `importlib_resources`.
import importlib_resources
## Note that the actual package could have been used,
# not just its (string) name, with something like:
# from XXX import YYY as data_pkg
data_pkg = '.'
fname = 'database.dat'
db_bytes = importlib_resources.read_binary(data_pkg, fname)
# or if a file-like stream is needed:
with importlib_resources.open_binary(data_pkg, fname) as db_file:
...