__all__
を使用せずに、パッケージ内のすべてのモジュールの名前をリストする簡単な方法はありますか?
たとえば、次のパッケージがある場合:
/testpkg
/testpkg/__init__.py
/testpkg/modulea.py
/testpkg/moduleb.py
このようなことをするための標準的な方法または組み込みの方法があるかどうか疑問に思っています:
>>> package_contents("testpkg")
['modulea', 'moduleb']
手動のアプローチは、パッケージのディレクトリを見つけるためにモジュール検索パスを反復処理することです。次に、そのディレクトリ内のすべてのファイルをリストし、一意の名前が付けられたpy/pyc/pyoファイルを除外し、拡張子を削除して、そのリストを返します。しかし、これはモジュールインポートメカニズムが既に内部で行っていることに対してかなりの量の作業のようです。その機能はどこでも公開されていますか?
たぶんこれはあなたが探していることをするでしょうか?
import imp
import os
MODULE_EXTENSIONS = ('.py', '.pyc', '.pyo')
def package_contents(package_name):
file, pathname, description = imp.find_module(package_name)
if file:
raise ImportError('Not a package: %r', package_name)
# Use a set because some may be both source and compiled.
return set([os.path.splitext(module)[0]
for module in os.listdir(pathname)
if module.endswith(MODULE_EXTENSIONS)])
python2.3以降 を使用すると、pkgutil
モジュールも使用できます。
>>> import pkgutil
>>> [name for _, name, _ in pkgutil.iter_modules(['testpkg'])]
['modulea', 'moduleb']
EDIT:このパラメーターはモジュールのリストではなく、パスのリストであることに注意してください。
>>> import os.path, pkgutil
>>> import testpkg
>>> pkgpath = os.path.dirname(testpkg.__file__)
>>> print [name for _, name, _ in pkgutil.iter_modules([pkgpath])]
import module
help(module)
私が何かを見落としているのか、答えが時代遅れなのかわからないが、
User815423426で述べられているように、これはライブオブジェクトに対してのみ機能し、リストされたモジュールは以前にインポートされたモジュールのみです。
パッケージ内のモジュールのリストは inspect を使用すると本当に簡単に思えます。
>>> import inspect, testpkg
>>> inspect.getmembers(testpkg, inspect.ismodule)
['modulea', 'moduleb']
これは、python 3.6以降で動作する再帰バージョンです。
import importlib.util
from pathlib import Path
import os
MODULE_EXTENSIONS = '.py'
def package_contents(package_name):
spec = importlib.util.find_spec(package_name)
if spec is None:
return set()
pathname = Path(spec.Origin).parent
ret = set()
with os.scandir(pathname) as entries:
for entry in entries:
if entry.name.startswith('__'):
continue
current = '.'.join((package_name, entry.name.partition('.')[0]))
if entry.is_file():
if entry.name.endswith(MODULE_EXTENSIONS):
ret.add(current)
Elif entry.is_dir():
ret.add(current)
ret |= package_contents(current)
return ret
pythonコード(コマンドプロンプトから))以外のパッケージに関する情報を表示する場合は、pydocを使用できます。
# get a full list of packages that you have installed on you machine
$ python -m pydoc modules
# get information about a specific package
$ python -m pydoc <your package>
Pydocと同じ結果になりますが、ヘルプを使用してインタープリター内で
>>> import <my package>
>>> help(<my package>)
Cdlearyの例に基づいて、すべてのサブモジュールの再帰バージョンリストパスを次に示します。
import imp, os
def iter_submodules(package):
file, pathname, description = imp.find_module(package)
for dirpath, _, filenames in os.walk(pathname):
for filename in filenames:
if os.path.splitext(filename)[1] == ".py":
yield os.path.join(dirpath, filename)
これにより、モジュールが一覧表示されます。
help("modules")