2012-09-20 103 views
5

我使用__init__.py在我做from myprojects.something import blabla時運行檢查。__init__.py的用法

今天我開始使用pyzmq,我想看看幕後發生了什麼。所以我瀏覽了github中的代碼,我發現(對我來說)__init__.py有一些奇怪的用法,我無法解釋自己。

例如zmq/core/__init__.py。請問zmq.core.__all____all__的值爲zmq.core.constants, zmq.core.error, zmq.core.message, etc.

zmq/__init__.py我看到在端

__all__ = ['get_includes'] + core.__all__ 

get_includes哪裏是基本上返回與該模塊的目錄和在父目錄utils目錄的列表的功能。

這是什麼意思? __init.py__做了什麼實現?

回答

11

__all__用於當有人做from module import *記錄here

唯一的解決方案是軟件包作者提供一個明確的 包的索引。導入語句使用以下 約定:如果程序包的__init__.py代碼定義了名爲 __all__的列表,則它將被視爲在遇到包import *時應導入的模塊名列表。 軟件包作者發佈 軟件包的新版本時,可以使此列表保持最新。如果軟件包作者沒有看到從其軟件包中導入*的用法,則封裝作者也可能決定不支持 。對於 例如,文件sounds/effects/__init__.py可能包含 下面的代碼:

__all__ = ["echo", "surround", "reverse"] 

這意味着from sound.effects import *將導入的聲音包的 三個已命名的子模塊。

__all__的一個用途是使包裝製造商能夠以適合他們的方式構造包裝,同時方便用戶使用。具體地,在pyzmq的情況下,它可以讓你編寫代碼,如:

import zmq 
print zmq.zmq_version() 

而不是必須使用完整的虛線模塊名稱:

print zmq.core.version.zmq_version() 

pyzmq的設計師使用__all__的包裝,以促進命名空間元素從嵌套模塊直到其名稱空間的頂層,因此用戶不會爲其包的結構所困擾。

+0

我在問這裏之前已閱讀過這部分文檔。但這仍然不能回答我的問題。也許我應該用另一種方式來問:我認爲使用'from bla import ble'的原因是您控制了您的命名空間,這意味着您決定將哪些符號添加到您的名稱空間中。 – Pablo

+0

正如C中使用'#include'的對比可能會導致已經定義的函數,變量等發生衝突一樣,你應該只導入你真正需要的符號。儘管我在python文檔中的某處閱讀過,使用'from bla import *'不是一個好習慣。如果是這樣,那麼爲什麼麻煩定義'__ all__'呢?並且''__all__ = ['get_includes'] + core .__ all__'在執行'import *'時會得到評估嗎?來自bla import *的 – Pablo

+1

不是一個好習慣,但有一些模塊通常是安全的。我經常從數學導入*做。這些模塊的文檔通常指出,它們被設計爲以這種方式使用,並且它們支持像__all__這樣的細節,以使它更容易一些。但從x導入*是stil的東西要謹慎使用,只有你知道它不會導致問題的包。 – TimothyAWiseman