119

Pythonパッケージの一部であるすべてのモジュールを見つける簡単な方法はありますか?私はこの古い議論を見つけましたが、これは実際には決定的なものではありませんが、os.listdir()に基づく独自のソリューションを展開する前に、明確な答えが欲しいです。

4

5 に答える 5

161

はい、あなたはそれに基づいたもの、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
于 2009-11-10T12:58:55.073 に答える
52

このジョブに適したツールは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メソッドが付属しています。

于 2009-11-10T15:15:48.003 に答える
2

これは私のために働きます:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key
于 2013-03-30T20:24:30.500 に答える
0

パッケージ内でライブで編集しているすべてのサブモジュールをリロードする方法を探していました。上記の回答/コメントの組み合わせなので、コメントではなく回答としてここに投稿することにしました。

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))
于 2019-11-03T03:46:05.187 に答える
-4

これが私の頭のてっぺんから離れた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、パッケージの「一部」の意味によって異なります。

于 2009-11-10T12:54:03.677 に答える