Может ли кто-нибудь предоставить мне хороший способ импорта целого каталога модулей?
У меня есть такая структура:
/Foo
bar.py
spam.py
eggs.py
Я попытался просто преобразовать его в пакет, добавив __init__.py
и сделав, from Foo import *
но это не сработало так, как я надеялся.
python
python-import
Эван Фосмарк
источник
источник
Ответы:
Перечислите все
.py
файлы python ( ) в текущей папке и поместите их как__all__
переменные в__init__.py
источник
if not os.path.basename(f).startswith('_')
или, по крайней мере,if not f.endswith('__init__.py')
до конца понимания спискаos.path.isfile(f)
естьTrue
. Это отфильтровывало бы битые символические ссылки и каталоги, какsomedir.py/
(угловой случай, я признаю, но все же ...)from . import *
после настройки,__all__
если вы хотите, чтобы субмодули были доступны с помощью.
(например, какmodule.submodule1
,module.submodule2
и т. Д.).Добавьте
__all__
переменную к__init__.py
содержанию:Смотрите также http://docs.python.org/tutorial/modules.html
источник
os.listdir()
, некоторая фильтрация, удаление.py
расширения и др__all__
.moduleName.varName
ref. stackoverflow.com/a/710603/248616Обновление в 2017 году: вы, вероятно, хотите использовать
importlib
вместо этого.Сделайте каталог Foo пакетом, добавив
__init__.py
. В это__init__.py
добавить:Поскольку вы хотите, чтобы он был динамическим (что может или не может быть хорошей идеей), перечислите все py-файлы с помощью list dir и импортируйте их примерно так:
Затем из вашего кода сделайте это:
Теперь вы можете получить доступ к модулям с
и т. д.
from Foo import *
не очень хорошая идея по нескольким причинам, включая конфликт имен и усложнение анализа кода.источник
__import__
хакером, я думаю, что было бы лучше добавить имена,__all__
а затем поместитьfrom . import *
в__import__
не для общего использования, он используетсяinterpreter
, используйтеimportlib.import_module()
вместо этого.from . import eggs
и т. Д.__init__.py
До того, как Python мог импортировать. Толькоimport eggs
я получаюModuleNotFoundError: No module named 'eggs'
при попыткеimport Foo
вmain.py
в каталоге выше.Продолжая ответ Михаила, я считаю, что нехакерский способ (например, не обрабатывать пути к файлам напрямую) заключается в следующем:
__init__.py
файл подFoo/
Ты получишь:
источник
RuntimeWarning
сообщения также можно избежать, если использовать full_package_name вообще:importer.find_module(package_name).load_module(package_name)
.RuntimeWarning
ошибки также можно избежать (возможно , в уродливом виде) путем импорта родителя (АКА DIRNAME). Один из способов сделать это -if dirname not in sys.modules: pkgutil.find_loader(dirname).load_module(dirname)
. Конечно, это работает, только еслиdirname
это однокомпонентный относительный путь; без косых черт Лично я предпочитаю подход @ Artfunkel использовать вместо этого базовое имя_пакета.Python, включите все файлы в каталоге:
Для новичков, которые просто не могут заставить его работать, которым нужны руки.
Создайте папку / home / el / foo и создайте файл
main.py
в / home / el / foo. Добавьте туда этот код:Сделать каталог
/home/el/foo/hellokitty
Создайте файл
__init__.py
в/home/el/foo/hellokitty
и поместите этот код там:Сделайте два файла Python:
spam.py
иham.py
под/home/el/foo/hellokitty
Определите функцию внутри spam.py:
Определите функцию внутри ham.py:
Запустить его:
источник
import *
считается плохой практикой программирования на Python. Как ты это делаешь без этого?Я устал от этой проблемы сам, поэтому я написал пакет под названием automodinit, чтобы исправить ее. Вы можете получить его по адресу http://pypi.python.org/pypi/automodinit/ .
Использование это так:
automodinit
пакет в вашиsetup.py
зависимости.Это оно! Отныне импорт модуля установит __all__ в список .py [co] файлов в модуле, а также будет импортировать каждый из этих файлов, как если бы вы ввели:
Поэтому эффект «из M import *» в точности совпадает с «import M».
automodinit
счастлив работать с внутренними архивами ZIP и поэтому безопасен для ZIP.Найл
источник
Я знаю, что обновляю довольно старый пост, и я пытался использовать
automodinit
, но обнаружил, что процесс установки нарушен для python3. Итак, основываясь на ответе Луки, я пришел к более простому ответу - который может не работать с .zip - на этот вопрос, поэтому я решил поделиться им здесь:в
__init__.py
модуле изyourpackage
:и в другом пакете ниже
yourpackage
:Затем вы загрузите все модули, которые находятся в пакете, и если вы напишите новый модуль, он также будет автоматически импортирован. Конечно, используйте такие вещи с осторожностью, с большими полномочиями возникают большие обязанности.
источник
источник
Я также столкнулся с этой проблемой, и это было мое решение:
Эта функция создает файл (в предоставленной папке) с именем
__init__.py
, который содержит__all__
переменную, которая содержит каждый модуль в папке.Например, у меня есть папка с именем,
Test
которая содержит:Поэтому в сценарии, в который я хочу импортировать модули, я напишу:
Это будет импортировать все из
Test
и__init__.py
файлTest
теперь будет содержать:источник
Пример Анурага с парой исправлений:
источник
Anurag Uniyal ответ с предложенными улучшениями!
источник
Смотри, что
__init__.py
определяет__all__
. Модули - пакеты док говоритисточник
Это лучший способ, который я нашел до сих пор:
источник
Используя
importlib
единственное, что вам нужно добавить, этоисточник
error: Type of __all__ must be "Sequence[str]", not "List[Module]"
. Определение__all__
не требуется, если используется этотimport_module
основанный подход.Посмотрите на модуль pkgutil из стандартной библиотеки. Это позволит вам делать именно то, что вы хотите, если у вас есть
__init__.py
файл в каталоге.__init__.py
Файл может быть пустым.источник
Для этого я создал модуль, который не зависит
__init__.py
(или любой другой вспомогательный файл) и заставляет меня печатать только следующие две строки:Не стесняйтесь повторно использовать или внести свой вклад: http://gitlab.com/aurelien-lourot/importdir
источник
Просто импортируйте их с помощью importlib и добавьте их
__all__
(add
действие необязательно) в recurse-__init__.py
пакете пакета.источник
py
Когда
from . import *
это недостаточно хорошо, это улучшение по сравнению с ответом Теда . В частности, использование__all__
этого подхода не является необходимым.Обратите внимание, что
module_name not in globals()
он предназначен для того, чтобы избежать повторного импорта модуля, если он уже импортирован, так как это может привести к циклическому импорту.источник