列出所有属于python包的模块?

有没有一种简单的方法来find所有的模块是Python包的一部分? 我发现了这个老的讨论 ,这并不是真正的结论,但是我很想在我推出基于os.listdir()的解决scheme之前有一个明确的答案。

是的,你需要基于pkgutil或类似的东西 – 这样你可以对待所有的软件包,不pipe它们是否在鸡蛋或拉链等等(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只列出了一层的模块。 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中定义的所有有趣的函数。

也许这意味着这些function不是“公共”界面的一部分,并且可能会发生变化。

但是,至less从Python 2.6(也许还有更早版本)开始,pkgutil带有一个recursion遍历所有可用模块的walk_packages方法。

这适用于我:

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

这是一个方法,从我的头顶:

 >>> 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文件中,那么这些模块可能不一定位于软件包的子目录中,所以这取决于你的软件包的“部分”。