簡體   English   中英

在Python中創建命名空間包的方法

[英]The way to make namespace packages in Python

分布式的命名空間包中 ,我知道我可以利用命名空間包將一個大的Python包分成幾個較小的包。 真的很棒。 該文件還提到:

順便提一下,請注意,在正常的Python包布局中,項目的源樹必須包含命名空間包'__init__.py文件(以及任何父包的__init__.py)。 這些__init__ .py文件必須包含以下行:

 __import__('pkg_resources').declare_namespace(__name__) 

此代碼確保命名空間包機制正在運行,並且當前包已注冊為命名空間包。

我想知道將相同的目錄層次結構保存到包的層次結構有什么好處嗎? 或者,這只是distribute / setuptools的命名空間包功能的技術要求?

當然,

我想提供一個子包foo.bar ,這樣我就必須構建以下文件夾層次結構並准備__init__.py以使setup.py工作在命名空間包中:

~foo.bar/
~foo.bar/setup.py
~foo.bar/foo/__init__.py    <=    one-lined file dedicated to namespace packages
~foo.bar/foo/bar/__init__.py
~foo.bar/foo/bar/foobar.py

我不熟悉命名空間包,但它在我看來1)foo / bar和2)(幾乎)單行__init__.py是例行任務。 它們確實提供了一些“這是命名空間包”的提示,但我認為我們已經在setup.py中提供了這些信息?

編輯:

如下面的塊所示,我可以在我的工作目錄中使用沒有該嵌套目錄和單行__init__.py的命名空間包嗎? 也就是說,我們可以通過只設置一行namespace_packages = ['foo']來請求setup.py自動生成這些嗎?

~foo.bar/
~foo.bar/setup.py
~foo.bar/src/__init__.py    <=    for bar package
~foo.bar/src/foobar.py

在導入子包時,命名空間包主要具有特定的效果。 基本上,這是導入foo.bar時發生的情況

  • 導入器掃描sys.path ,查找看起來像foo東西。
  • 當它找到某些東西時,它會看到發現的foo里面的bar
  • 如果沒有找到bar
    1. 如果foo是普通包,則會引發ImportError ,表明foo.bar不存在。
    2. 如果foo命名空間包,則導入器會返回查看sys.path以查找foo的下一個匹配項。 只有在所有路徑都已耗盡時才會引發ImportError

這就是它的作用 ,但並沒有解釋為什么你會這么想。 假設你設計了一個很大的,有用的庫( foo ),但作為其中的一部分,你還開發了一個小但非常有用的實用程序( foo.bar ),其他python程序員發現它很有用,即使它們沒有用於更大的圖書館

您可以將它們一起分發為一個包的大塊(就像您設計的那樣),即使大多數使用它的人只會導入子模塊。 你的用戶會發現這非常不方便,因為他們必須下載整個東西(所有200MB!),即使他們真的只對10行實用程序類感興趣。 如果你有一個開放的許可證,你可能會發現有幾個人最終要求它,現在你的實用程序模塊有六個不同版本。

您可以重寫整個庫,以便實用程序位於foo命名空間之外(只是bar而不是foo.bar )。 您將能夠單獨分發該實用程序,並且您的一些用戶會很高興,但這是很多工作,特別是考慮到實際上很多用戶使用整個庫,因此他們將不得不重寫他們的程序使用新的。

所以你真正想要的是一種foo.bar安裝foo.bar的方法,但是當你想要的時候也很樂意與foo共存。

命名空間包允許這兩個完全獨立的foo包安裝可以共存。 setuptools會認識到這兩個包被設計成彼此相鄰並禮貌地移動文件夾/文件,使得它們都在路徑上並顯示為foo ,一個包含foo.bar而另一個包含其余的foo

你將有兩個不同的setup.py腳本,每個腳本一個。 兩個包中的foo/__init__.py必須指示它們是命名空間包,因此無論首先發現哪個包,導入器都知道繼續。

暫無
暫無

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

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