簡體   English   中英

在Python模塊分發中查找文件

[英]Finding a file in a Python module distribution

我編寫了一個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”文件,該文件與訪問數據庫的代碼一起安裝。

嘗試使用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獲取egg頁面和pkg_resources頁面上的資源的更多討論。

另請注意,在可能的情況下,建議使用pkg_resources.resource_stream或pkg_resources.resource_string,因為如果包是egg的一部分,resource_filename會將文件復制到臨時目錄。

使用pkgutil.get_data 它是pkg_resources.resource_stream的表兄弟,但在標准庫中,應該使用平面文件系統安裝以及壓縮包和其他導入程序。

這可能就是這樣做的方式,而不需要使用更高級的東西,比如使用setuptools安裝它們所屬的文件。

請注意,該方法存在問題,因為在具有真實安全框架(UNIX等)的操作系統上,運行腳本的用戶可能無權訪問安裝它的系統目錄中的數據庫。

使用標准的Python-3.7庫的importlib.resources模塊 ,它比setuptools:pkg_resources 更有效 setuptools:pkg_resources (在以前的Python版本中,使用backported importlib_resources )。

注意:為此,數據文件所在的文件夾必須是常規的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:
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM