本问题已经有最佳答案,请猛点这里访问。
我已经编写了一个Python程序包,其中包含一个bsddb数据库,该数据库包含用于更耗时的计算之一的预先计算的值。 为简单起见,我的安装脚本将数据库文件安装在与访问数据库的代码相同的目录中(在Unix上,类似于/usr/lib/python2.5/site-packages/mypackage/)。
如何存储数据库文件的最终位置,以便我的代码可以访问它? 现在,我正在使用基于访问数据库的模块中__file__变量的黑客:
1
| dbname = os.path.join(os.path.dirname(__file__),"database.dat") |
它可以工作,但似乎...有点黑。 有一个更好的方法吗? 我想让安装脚本从distutils模块中获取最终安装位置,并将其填充到一个" dbconfig.py"文件中,该文件与访问数据库的代码一起安装。
尝试使用pkg_resources,它是setuptools的一部分(并且在我现在可以访问的所有python上都可用):
1 2 3 4 5
| >>> 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,因为如果包是鸡蛋的一部分,则resource_filename会将文件复制到一个临时目录中。
使用pkgutil.get_data。它是pkg_resources.resource_stream的表亲,但在标准库中,并且应与平面文件系统安装以及压缩包和其他导入程序一起使用。
这可能是这样做的方法,而无需诉诸更高级的功能,例如使用setuptools将文件安装在它们所属的位置。
请注意,这种方法存在问题,因为在具有真正安全框架(例如UNIX等)的OS上,运行脚本的用户可能无权访问安装了DB的系统目录中的DB。
使用标准的Python-3.7库的importlib.resources模块,
比setuptools:pkg_resources更有效
(在以前的Python版本中,使用向后移植的importlib_resources库)。
注意:为使此工作正常,数据文件所在的文件夹必须是常规的python-package。这意味着您必须在其中添加__init__.py文件(如果尚未存在)。
然后您可以像这样访问它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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:
... |