2011-12-17 57 views
5

我想知道爲什麼在導入包時,在Python包中包含子模塊的目錄(子包)顯示爲符號。舉例來說,如果我有這個包:Python的導入包 - 子包不應該出現在符號表

PyModTest/      Top-level package 
      __init__.py    Initialize the package 
      Source/     Subpackage holding source files 
       __init__.py 
       WildMod.py  Submodule containing a function: 'WildFunc' 

其中頂層__init__.py看起來是這樣的:

#!/usr/bin/env python 

from Source.WildMod import WildFunc 

,併爲完整起見,下級__init__.py看起來是這樣的:

#!/usr/bin/env python 

__all__ = ["WildMod"] 

好了,現在我開了解釋,導入模塊,並期待在符號:

>>> import PyModTest 
>>> dir(PyModTest) 
['Source', 'WildFunc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__'] 

看到了'Source'模塊出現了,儘管我從未專門導入它!

我想看到的唯一符號(除了私人的)是我的'WildFunc'。有什麼方法可以隱藏「Source」包嗎?

回答

6

兩兩件事需要注意:

  • 在Python,模塊是實際的對象,他們的名字之間出現的點代表一個實際屬性訪問
  • 你正在做一個相對進口,這意味着Source實際上PyModTest.Source(感謝TokenMacGuy指出了這一點)

所以:以進口PyModTest.Source.WildMod.WildFunc,Python有到

  1. 進口PyModTest(其已經由你完成)
  2. 檢查,看它是否有一個叫做Source的屬性,如果沒有,通過導入它從PyModTest/Source/__init__.py
  3. 檢查創建屬性,看看是否有一個屬性叫WildMod,如果沒有,通過導入它從PyModTest/Source/WildMod.py
  4. 檢查創建屬性,看看是否有
稱爲 WildFunc(其它)的屬性3210

一些相關的細節在PEP 302Python language reference中討論。

在機制中更加深入,虛線名稱導入被拆分爲 其組件。對於「import spam.ham」,首先「import spam」爲 完成,並且僅當成功時爲「ham」作爲子模塊 導入爲「spam」。

如果你不想有一個名爲Source變量,這是容易解決:導入功能只是del Source之後。但請記住,它將阻止稍後運行的任何代碼訪問PyModTest.Source.<anything>(除了WildFunc,因爲您已保存對此的引用)。我肯定會建議只是忽略對Source的引用,而不是刪除它,因爲它不會傷害任何東西。

+0

太棒了,這是有道理的。感謝您對'del Source'的建議:) – rokuingh 2011-12-17 01:02:51