簡體   English   中英

Python setup.py:如何包含本地包依賴?

[英]Python setup.py: how to include local package dependency?

這個問題幾乎不言自明。 我有一個 .zip 包依賴項,我需要將它包含在我的 python 包安裝中。 那么如何在我的setup.py包含這個本地依賴? 我有install_requires但這從 PyPI 加載了我的依賴包,這在這種情況下不是我想要的。

我的項目中最相關的文件結構如下:

myproject
|- setup.py
|- mypackage
   |- __init__.py
   |- vendor
      |- __init__.py
      |- dependencies
         |- StreamingDataReader.zip

然后我嘗試...

include_package_data=True,
package_data={
    'StreamingDataReader': ['mypackage/vendor/dependencies/StreamingDataReader.zip'],
}

......沒有成功。 我的代碼仍然無法找到包: ImportError: No module named 'StreamingDataReader'

這是一個老問題,但我對此有話要說,所以我發帖了。

你在這里有兩個不同的問題。 首先是 zip 文件需要包含在您的發行版中。 為此,請按照您的意圖使用package_data ,但您需要為您的包指定要包含其中的哪些數據。 您可以按如下方式執行此操作:

   package_data= {"mypackage": ["vendor/dependencies/StreamingDataReader.zip"]}

不要同時使用include_package_data 這會在MANIFEST.in查找數據並忽略package_data參數。 setuptools設計真的很糟糕,用於管理這個。 對於二進制和源代碼打包,我發現的最佳建議是確保所有數據都在包目錄中,並使用package_data而不是其他任何東西。

您的第二個問題是您希望能夠導入StreamingDataReader 不幸的是,據我所知,沒有辦法一起做這個pip使用pip install ,沒有別的。 你有兩個明顯的選擇:

(1) 您可以包含一個requirements.txt文件並將 zip 文件列為需求,並讓人們在pip install您的項目之前執行pip install -r requirements.txt 您的requirements.txt文件將如下所示:

./mypackage/vendor/dependencies/StreamingDataReader.zip

但是要求用戶這樣做可能會帶來不可接受的痛苦,並且對於依賴您的軟件包的任何人都不起作用。

(2) 蠻力。 只需使用zipfile來擴展包。

我將假設StreamingDataReader.zip文件是一個 Python 包 zip,在頂層有一個目錄(我假設它稱為StreamingDataReader ),其中包含一個頂層setup.py和一個子目錄,假設它稱為StreamingDataReader ,其中包含實際的軟件。 換句話說,我假設你的 zip 看起來像這樣:

StreamingDataReader/
StreamingDataReader/setup.py
StreamingDataReader/StreamingDataReader/__init__.py

等等。我還將假設您正在運行 Python 3.3 或更高版本,其中不再需要__init__.py文件來創建包層次結構。 (在以前的版本中,您需要操作sys.path ,這沒什么大不了的,但現在更容易了。)因此vendor/__init__.py不會為您做任何工作。

順便說一下,這個解決方案假設運行你的軟件的人對包含它的目錄有寫權限。

將以下內容放在您的頂層__init__.py

import zipfile, pathlib

_mpath = pathlib.Path(__file__).resolve().parent
_sdrDir = mpath.joinpath("vendor", "dependencies", "StreamingDataReader")
if not _sdrDir.is_dir():
    _z = zipfile.Zipfile(sdrDir.parent.joinpath("StreamingDataReader.zip"), "r")
    _z.extractall(sdrDir.parent)
    _z.close()
    del _z
# cleanup
del _mpath
del _sdrDir

一旦你這樣做了,你就可以

import mypackage.vendor.dependencies.StreamingDataReader.StreamingDataReader as StreamingDataReader

隨心所欲。

然后,最后,在您的包的setup.py中,您需要包含StreamingDataReader依賴項,因為您沒有使用pip遞歸安裝它。

是的,這是很多工作。 但據我所知,Python 安裝機制中沒有任何工具可以從您自己提供的 zip 文件中安裝包。

暫無
暫無

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

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