列出一个Python包中的所有模块?

135 投票
7 回答
111634 浏览
提问于 2025-04-15 15:51

有没有简单的方法可以找到一个Python包里面所有的模块?我找到了一些旧的讨论,虽然不太明确,但我希望在自己用os.listdir()写解决方案之前,能有一个确切的答案。

7 个回答

3

这个对我有效:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key
53

这个工作最合适的工具是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只会列出一层深的模块,而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方法,可以递归地遍历所有可用的模块。

176

是的,你需要使用像 pkgutil 这样的工具,这样你就可以把所有的包都当成一样的来处理,不管它们是放在 eggs 还是 zips 里(这时候用 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

撰写回答