Список всех модулей, которые являются частью пакета Python?

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

 S.Lott10 нояб. 2009 г., 22:02
@ kaizer.se: "Программа должна обнаруживать себя всякий раз, когда я или какой-либо другой разработчик добавляет новый плагин "   Какое это имеет отношение к вопросу? Когда я читаю вопрос, почти ни одно из этих слов не появляется. Как возникает вопрос о странном случае, когда кто-то тайно добавляет компоненты?
 u0b34a0f6ae10 нояб. 2009 г., 20:49
ls в оболочке не адекватно. Программа должна обнаруживать себя всякий раз, когда я или какой-либо другой разработчик добавляет новый плагин, сохраняя новый модуль (скажем, new.py) внутри подпакета плагина. Программа отобразит список обнаруженных плагинов.
 u0b34a0f6ae10 нояб. 2009 г., 23:03
@static_rtti: Можно ли объяснить, какую проблему вы решаете? Признаете ли выобнаружить подмодули пакета во время выполнения " USECASE?
 static_rtti10 нояб. 2009 г., 14:06
Бонусный вопрос: как правильно импортировать найденные модули?
 u0b34a0f6ae10 нояб. 2009 г., 16:48
зачем изобретать велосипед? Если python приобретает гипермодули в Python 4, pkgutil и обновляется с этим, мой код все равно будет работать. Мне нравится использовать доступные абстракции. Используйте предоставленный очевидный метод, он протестирован и известен как работающий. Воплощая это ... теперь вы должны найти и обойти каждый угловой случай самостоятельно.
 u0b34a0f6ae10 нояб. 2009 г., 18:24
@ S.Lott: То есть каждый раз, когда приложение запускается, оно разархивирует свое собственное яйцо, если оно установлено внутри, просто чтобы проверить это? Пожалуйста, отправьте патч против моего проекта, чтобы заново изобрести колесо в этой функции:git.gnome.org/cgit/kupfer/tree/kupfer/plugins.py#n17, Пожалуйста, учитывайте как яйца, так и нормальные каталоги, не превышайте 20 строк.
 S.Lott10 нояб. 2009 г., 14:38
Какие'не так с чтением исходного каталога? Какая дополнительная информация вам нужна? Какие'не так сls (или жеdir)?
 S.Lott10 нояб. 2009 г., 20:11
@ kaiser.se: каккаждый раз, когда приложение запускается, оно разархивирует свое яйцо иметь какое-либо отношение к этому вопросу? Пожалуйста, уточните этот вопрос. Почемуls не подходит? Пожалуйста, обратите внимание на то, почему - в этом конкретном вопросе -ls не адекватно. Я только хочу уточнить смысл этого вопроса.
 S.Lott10 нояб. 2009 г., 15:22
@ Kaizer.se: молнии можно тривиально изучить, чтобы увидеть их содержимое. Я нене понимаю вопрос. Какая дополнительная информация требуется, чем то, что обычно доступно через обычные методы ОС? Я'Я надеюсь на некоторую ясность в отношении того, какой ценной информации не хватает.
 u0b34a0f6ae10 нояб. 2009 г., 20:47
@ S.Lott: Вы спрашиваете о руководствеls по мне в скорлупе, или актуальноos.popen("ls").read() или ты действительно имеешь ввиду?os.listdir
 S.Lott10 нояб. 2009 г., 17:05
@ Kaizer.se. Какой ручной индекс? Я нене понимаю вопрос. Какие'не так сls? Когда я хочу знать модули в пакете, я используюls -r в файловой системе. Или я разархивирую яйцо и используюls -r, Почему это неадекватно? Что еще требуется?
 u0b34a0f6ae10 нояб. 2009 г., 16:51
@ S.Lott: Ах, это все о программном обнаружении подмодулей. Код, который я разместил, взят из приложения, которое загружает плагины, которые являются субмодулями, в пакет плагинов - нет необходимости сохранять индекс вручную в программе, так как pkgutil может перечислять доступные плагины.
 u0b34a0f6ae10 нояб. 2009 г., 20:52
@ S.Lott: Почему ты неЯ не понимаю, что это важно, это то, что вы можетеТ понять. Обнаружение этого программно о том, чтоприложение интересует содержимое пакета, а не пользователь.
 u0b34a0f6ae10 нояб. 2009 г., 14:43
@ S.Lott: есть более общие решения, пакеты python не всегда находятся в каталогах в файловой системе, но также могут быть внутри zips.
 static_rtti12 нояб. 2009 г., 20:52
Конечно, я имею в виду программно! Иначе я бы нет упомянулвыкатываете собственное решение с помощью os.listdir () "
 u0b34a0f6ae10 нояб. 2009 г., 20:54
Извините, это то, что я Можно'Т понять.

Ответы на вопрос(4)

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

import types

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

Чтобы перечислить все модули в вашей системе:

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

Документация по пкгутил (http://docs.python.org/library/pkgutil.html) не перечисляет все интересные функции, определенные в /usr/lib/python2.6/pkgutil.py.

Возможно, это означает, что функции не являются частьюобщественности» интерфейс и могут быть изменены.

Однако, по крайней мере, в Python 2.6 (и, возможно, более ранних версиях?) Pkgutil поставляется с методом walk_packages, который рекурсивно просматривает все доступные модули.

 Apostolos27 февр. 2018 г., 10:18
Я понимаю, что ты имеешь в виду @unutbu ... Действительно, я пытался спип»  и работает нормально. Спасибо!
 unutbu24 февр. 2018 г., 02:06
@Apostolos: должно быть два подчеркивания (_) до и послеpath -- то есть,использованиеpackage.__path__ скорее, чемpackage._path_, Это может быть проще попробовать вставлять код, а не набирать его заново.
 Mechanical snail01 сент. 2011 г., 10:12
walk_packages сейчас в документации:docs.python.org/library/pkgutil.html#pkgutil.walk_packages
 Apostolos23 февр. 2018 г., 22:51
Ваш второй пример выдает следующую ошибку:AttributeError: 'модуль» объект не имеет атрибута_дорожка_'" - Я не'проверить это с 'SciPy» но с несколькими другими пакетами. Это как-то связано с версией Python? (Я использую Python 2.7)
 unutbu26 февр. 2018 г., 12:46
@Apostolos: убедитесь, что переменнаяpackage указывает на пакет, а не на модуль. Модули - это файлы, а пакеты - это каталоги.Все пакеты имеют__path__ атрибут (... если кто-то не удалил атрибут по какой-то причине.)
 Apostolos26 февр. 2018 г., 08:58
Их было двое, когда я написал комментарий! :) Но они были лишены системой. Виноват; Я должен был поставить три подчеркивания. Но тогда, это было бы хорошо, если бы я хотел использовать курсив, который я нет! ... Это'Ситуация потери-потери. :) Во всяком случае, когда я запускаю код, я использовал два из них, конечно. (Я скопировал и вставил код.)

Вот'С одной стороны, с моей головы:

>>> 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)="">]
</module></module></module></module></module>

Это, безусловно, может быть очищено и улучшено.

РЕДАКТИРОВАТЬ: Вот'немного более приятная версия:

>>> [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']
</module></module></module></module></module>

НОТА: Также будут найдены модули, которые могут не обязательно находиться в подкаталоге пакета, если онипереехал в его__init__.py файл, так что это зависит от того, что вы подразумеваете под "часть" упаковка.

 u0b34a0f6ae10 нояб. 2009 г., 14:09
извините, это бесполезно. Помимо ложных срабатываний, он также найдет только импортированные субмодули пакетов.
Решение Вопроса

Да, вы хотите что-то на основе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
 Apostolos23 февр. 2018 г., 23:46
Ваш первый пример выдает следующую ошибку:AttributeError: 'модуль» объект не имеет атрибута_дорожка_'" Это как-то связано с версией Python? (Я использую Python 2.7)
 MestreLion05 нояб. 2013 г., 23:41
что этоimporter вернулсяpkgutil.iter_modules? Могу ли я использовать его для импорта модуля вместо того, чтобы использовать это "хак»  ?__import__(modname, fromlist="dummy")
 Apostolos17 апр. 2018 г., 08:10
Нет, я использовал два подчеркивания, но stackoverflow съел одно, считая его курсивом.
 C.R. Sharat12 апр. 2017 г., 14:01
@chrisleague Я использовал метод ur с python 2.7, но теперь мне нужно двигаться дальше с python 3.4, так что вы знаете, что в python 3 pkutil.iter_modules возвращает (module_finder, name, ispkg) вместо (module_loader, name, ispkg). Что я могу сделать, чтобы он работал как предыдущий?
 chrisleague07 июн. 2014 г., 02:55
Я был в состоянии использовать импортер, как это:m = importer.find_module(modname).load_module(modname) а потомm это модуль, например, так:m.myfunc()
 therealmitchconnors13 апр. 2018 г., 20:36
@Apostolos, вы используете только одно подчеркивание по обе стороны пути (т.е._path_). Там должно быть два с каждой стороны, в общей сложности четыре (т.е.__path__).

Ваш ответ на вопрос