Список всех модулей, которые являются частью пакета Python? - PullRequest
86 голосов
/ 10 ноября 2009

Есть ли простой способ найти все модули, которые являются частью пакета python? Я нашел это старое обсуждение , которое на самом деле не является окончательным, но я бы хотел получить определенный ответ, прежде чем развернуть свое собственное решение, основанное на os.listdir ().

Ответы [ 4 ]

129 голосов
/ 10 ноября 2009

Да, вы хотите что-то на основе 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
41 голосов
/ 10 ноября 2009

Правильный инструмент для этой работы - 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, который рекурсивно просматривает все Доступные модули.

3 голосов
/ 31 марта 2013

Это работает для меня:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key
0 голосов
/ 10 ноября 2009

Вот один из способов, с моей головы:

>>> 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, поэтому это зависит от того, что вы подразумеваете «часть» пакета.

...