Как загрузить все модули в папке? - PullRequest
223 голосов
/ 29 июня 2009

Может ли кто-нибудь предоставить мне хороший способ импорта целого каталога модулей?
У меня есть такая структура:

/Foo
    bar.py
    spam.py
    eggs.py

Я попытался просто преобразовать его в пакет, добавив __init__.py и выполнив from Foo import *, но это не сработало так, как я надеялся.

Ответы [ 16 ]

4 голосов
/ 13 июня 2014

Anurag Uniyal answer с предлагаемыми улучшениями!

#!/usr/bin/python
# -*- encoding: utf-8 -*-

import os
import glob

all_list = list()
for f in glob.glob(os.path.dirname(__file__)+"/*.py"):
    if os.path.isfile(f) and not os.path.basename(f).startswith('_'):
        all_list.append(os.path.basename(f)[:-3])

__all__ = all_list  
3 голосов
/ 02 июля 2014

Это лучший способ, который я нашел до сих пор:

from os.path import dirname, join, isdir, abspath, basename
from glob import glob
pwd = dirname(__file__)
for x in glob(join(pwd, '*.py')):
    if not x.startswith('__'):
        __import__(basename(x)[:-3], globals(), locals())
3 голосов
/ 29 июня 2009

Смотрите, что ваш __init__.py определяет __all__. Модули - пакеты документ говорит

Файлы __init__.py необходимы для того, чтобы Python рассматривал каталоги как содержащие пакеты; это сделано для предотвращения непреднамеренного скрытия действительными модулями каталогов с общим именем, например, строки, которые встречаются позже в пути поиска модулей. В простейшем случае __init__.py может быть просто пустым файлом, но он также может выполнить код инициализации для пакета или установить переменную __all__, описанную ниже.

...

Единственное решение для автора пакета - предоставить явный индекс пакета. В операторе импорта используется следующее соглашение: если код пакета __init__.py определяет список с именем __all__, он считается списком имен модулей, которые следует импортировать при обнаружении импорта из пакета *. Автор пакета должен обновлять этот список после выпуска новой версии пакета. Авторы пакета могут также принять решение не поддерживать его, если они не видят использования для импорта * из своего пакета. Например, файл sounds/effects/__init__.py может содержать следующий код:

__all__ = ["echo", "surround", "reverse"]

Это будет означать, что from sound.effects import * будет импортировать три именованных подмодуля звукового пакета.

1 голос
/ 19 ноября 2014

Я создал для этого модуль, который не использует __init__.py (или любой другой вспомогательный файл) и заставляет меня печатать только следующие две строки:

import importdir
importdir.do("Foo", globals())

Не стесняйтесь повторно использовать или внести свой вклад: http://gitlab.com/aurelien-lourot/importdir

1 голос
/ 08 февраля 2011

Посмотрите на модуль pkgutil из стандартной библиотеки. Это позволит вам делать именно то, что вы хотите, если у вас есть файл __init__.py в каталоге. Файл __init__.py может быть пустым.

0 голосов
/ 18 января 2018

Просто импортируйте их с помощью importlib и добавьте их к __all__ (действие add необязательно) в recurse в __init__.py пакета.

/Foo
    bar.py
    spam.py
    eggs.py
    __init__.py

# __init__.py
import os
import importlib
pyfile_extes = ['py', ]
__all__ = [importlib.import_module('.%s' % filename, __package__) for filename in [os.path.splitext(i)[0] for i in os.listdir(os.path.dirname(__file__)) if os.path.splitext(i)[1] in pyfile_extes] if not filename.startswith('__')]
del os, importlib, pyfile_extes
...