最近的 python 專案有個需求,想要匯入某個目錄下所有的 python 模組 (module),

用來測試這個匯入的動作會不會造成一些問題~

平常匯入的方式是用 from xxx import yyy 或是 import yyy,

但這種寫法必須先知道 xxx 或 yyy 的名稱才行...

 

python 是有個 __import__() 函式,可以指定一個模組的名稱 (如 a.b.c) 來匯入,

因此問題就轉變成:假設指定某個目錄 a/b,要如何取得目錄下所有的模組 c* 的名稱呢?

 

上網查了一下,有人是直接用 os.listdir() 去列出目錄下所有的檔案,

但後來看到一個使用 pkgutil.iter_modules() 的方式,感覺比較像正規作法~

pkgutil.iter_modules() 裡面要帶一個 list 參數,表示要搜尋的路徑列表,

像我想查 tool 目錄下所有的模組,就用 pkgutil.iter_modules(["tool"]),傳回值是一個 generator:

>>> import pkgutil

>>> pkgutil.iter_modules(["tool"])
<generator object iter_modules at 0x10fae4050>

 

這個 generator 傳出來的是一個 (module_loader, name, ispkg) 的 tuple:

>>> pprint([x for x in pkgutil.iter_modules(["tool"])])
[(<pkgutil.ImpImporter instance at 0x10fb394d0>, 'chardet', True),
 (<pkgutil.ImpImporter instance at 0x10fb394d0>, 'cmd2', True),
 (<pkgutil.ImpImporter instance at 0x10fb394d0>, 'dpkt', True),
 (<pkgutil.ImpImporter instance at 0x10fb394d0>, 'ipaddr', True),
 (<pkgutil.ImpImporter instance at 0x10fb394d0>, 'pyparsing', True)]

 

下面是一個例子,我用 pkgutil.iter_modules() 找出 tool 目錄下所有的模組,

接著用 __import__() 確認這些模組是否都能被成功的匯入 (import):

for _, name, _ in pkgutil.iter_modules(["tool")]):
    assert __import__("mypkg.tool.%s" % (name)) is not None

 

參考資料:Is there a standard way to list names of Python modules in a package?

 

文章標籤
創作者介紹

亂打一通的心情日記

ephrain 發表在 痞客邦 PIXNET 留言(0) 人氣()