[Python] 用 pkgutil.iter_modules() 列出某目錄下所有的模組 (module) 名稱
最近的 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?
(本頁面已被瀏覽過 3,140 次)