Finding a file in a Python module distribution

你。 提交于 2019-11-29 01:05:29
Aaron Maenpaa

Try using pkg_resources, which is part of setuptools (and available on all of the pythons I have access to right now):

>>> 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'

There's more discussion about using pkg_resources to get resources on the eggs page and the pkg_resources page.

Also note, where possible it's probably advisable to use pkg_resources.resource_stream or pkg_resources.resource_string because if the package is part of an egg, resource_filename will copy the file to a temporary directory.

Use pkgutil.get_data. It’s the cousin of pkg_resources.resource_stream, but in the standard library, and should work with flat filesystem installs as well as zipped packages and other importers.

That's probably the way to do it, without resorting to something more advanced like using setuptools to install the files where they belong.

Notice there's a problem with that approach, because on OSes with real a security framework (UNIXes, etc.) the user running your script might not have the rights to access the DB in the system directory where it gets installed.

Use the standard Python-3.7 library's importlib.resources module, which is more efficient than setuptools:pkg_resources (on previous Python versions, use the backported importlib_resources library).

Attention: For this to work, the folder where the data-file resides must be a regular python-package. That means you must add an __init__.py file into it, if not already there.

Then you can access it like this:

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:
    ...
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!