Pythonパッケージの一部であるすべてのモジュールを見つける簡単な方法はありますか?私はこの古い議論を見つけましたが、これは実際には決定的なものではありませんが、os.listdir()に基づく独自のソリューションを展開する前に、明確な答えが欲しいです。
5 に答える
はい、あなたはそれに基づいたもの、pkgutil
または同様のものが必要です-このようにして、卵やジッパーなどにあるかどうかに関係なく、すべてのパッケージを同じように扱うことができます(os.listdirは役に立ちません)。
import pkgutil
# this is the package we are inspecting -- for example 'email' from stdlib
import email
package = email
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__):
print "Found submodule %s (is a package: %s)" % (modname, ispkg)
それらもインポートする方法は?__import__
通常どおりに使用できます。
import pkgutil
# this is the package we are inspecting -- for example 'email' from stdlib
import email
package = email
prefix = package.__name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__, prefix):
print "Found submodule %s (is a package: %s)" % (modname, ispkg)
module = __import__(modname, fromlist="dummy")
print "Imported", module
このジョブに適したツールはpkgutil.walk_packagesです。
システム上のすべてのモジュールを一覧表示するには:
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
print(modname)
walk_packagesはすべてのサブパッケージをインポートしますが、サブモジュールはインポートしないことに注意してください。
特定のパッケージのすべてのサブモジュールを一覧表示する場合は、次のようなものを使用できます。
import pkgutil
import scipy
package=scipy
for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__,
prefix=package.__name__+'.',
onerror=lambda x: None):
print(modname)
iter_modulesは、1レベルの深さのモジュールのみをリストします。walk_packagesは、すべてのサブモジュールを取得します。たとえば、scipyの場合、walk_packagesは
scipy.stats.stats
iter_modulesはのみを返しますが
scipy.stats
pkgutilのドキュメント(http://docs.python.org/library/pkgutil.html)には、/ usr / lib / python2.6/pkgutil.pyで定義されているすべての興味深い関数がリストされているわけではありません。
おそらくこれは、関数が「パブリック」インターフェースの一部ではなく、変更される可能性があることを意味します。
ただし、少なくともPython 2.6(およびおそらく以前のバージョン?)の時点では、pkgutilには、使用可能なすべてのモジュールを再帰的にウォークスルーするwalk_packagesメソッドが付属しています。
これは私のために働きます:
import types
for key, obj in nltk.__dict__.iteritems():
if type(obj) is types.ModuleType:
print key
パッケージ内でライブで編集しているすべてのサブモジュールをリロードする方法を探していました。上記の回答/コメントの組み合わせなので、コメントではなく回答としてここに投稿することにしました。
package=yourPackageName
import importlib
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__, prefix=package.__name__+'.', onerror=lambda x: None):
try:
modulesource = importlib.import_module(modname)
reload(modulesource)
print("reloaded: {}".format(modname))
except Exception as e:
print('Could not load {} {}'.format(modname, e))
これが私の頭のてっぺんから離れた1つの方法です:
>>> import os
>>> filter(lambda i: type(i) == type(os), [getattr(os, j) for j in dir(os)])
[<module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'errno' (built-in)>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'sys' (built-in)>]
それは確かにクリーンアップされ、改善される可能性があります。
編集:これは少し良いバージョンです:
>>> [m[1] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
[<module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'errno' (built-in)>, <module 'sys' (built-in)>]
>>> [m[0] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
['_copy_reg', 'UserDict', 'path', 'errno', 'sys']
注:これは、ファイルに取り込まれている場合、必ずしもパッケージのサブディレクトリにあるとは限らないモジュールも検出するため__init__.py
、パッケージの「一部」の意味によって異なります。