2013-02-15 72 views
0

我在我的模塊的__init__.py中使用下面的代碼來填充__all__,如果有更有效的方法,我就會徘徊。有任何想法嗎?在__init__.py中遞歸填充__all__

import fnmatch 
import os 

__all__ = [] 
for root, dirnames, filenames in os.walk(os.path.dirname(__file__)): 
    root = root[os.path.dirname(__file__).__len__():] 
    for filename in fnmatch.filter(filenames, "*.py"): 
     __all__.append(os.path.join(root, filename[:-3])) 
+0

如果你想導出所有東西,你真的需要'__all__'嗎?如果未定義'__all__',默認行爲是導出所有內容。 – alexis 2013-02-15 22:22:07

+0

@alexis確實如此,但我希望能夠*排除*一些,所以我想用所有內容填充__all__,然後刪除那些我不想公開的內容。 – 2013-02-16 12:29:28

回答

2

您可能不應該這樣做:默認行爲import是相當靈活的。如果你不想要一個模塊(或任何其他變量)被自動導出,給它一個以_開頭的名字,並且python不會導出它。這是標準的python方式,重新發明輪子被認爲是和諧的。另外,不要忘記,除模塊之外的其他東西可能需要導出;一旦你設置了__all__,你還需要找到並導出它們。

但是,您仍然要問如何最好地生成可導出模塊的列表。既然你不能導出什麼是不存在的,我只是檢查已知的主模塊的模塊是什麼你自己:

basedir = os.path.dirname(__file__) 
for m in sys.modules: 
    if m in locals() and not m.startswith('_'): # Only export regular names 
     mod = locals()[m] 
     if '__file__' in mod.__dict__ and mod.__file__.startswith(basedir): 
      print m 

sys.modules包括每一個蟒蛇已加載模塊的名稱,其中包括許多有沒有被導出到你的主模塊 - 所以我們檢查它們是否在locals()

這比掃描文件系統更快,並且比您假設目錄樹中的每個.py文件都以某種方式最終成爲頂級子模塊更爲強大。自然地,您應該在__init__.py的末尾附近運行此代碼,當所有內容都已加載完畢時。