Дополнительно
Импорт файлов из другой папки
У меня есть следующая структура папок.
application / app / folder / file.py
и я хочу импортировать некоторые функции из file.py в другой файл Python, который находится в
application / app2 / some_folder / some_file.py
Я пробовал
из application.app.folder.file import func_name
и некоторые другие попытки, но пока я не смог правильно импортировать. Как я могу это сделать?
1168
22
По умолчанию вы не можете. При импорте файла Python ищет только текущий каталог, каталог, из которого работает скрипт точки входа, и
sys.path
, который включает в себя такие места, как каталог установки пакета (на самом деле это немного сложнее, чем этот, но это охватывает большинство случаев).Однако вы можете добавить к пути Python во время выполнения:
Ничего плохого в:
Просто убедитесь, что
folder
также содержит__init__.py
, что позволяет включать его в пакет. Не уверен, почему другие ответы говорят оPYTHONPATH
.Когда модули находятся в параллельных местах, как в вопросе:
Это сокращение делает один модуль видимым для другого:
Я думаю, что специальным способом было бы использовать переменную среды
PYTHONPATH
, как описано в документации: Python2, Python3Первые импортные системы
Второй добавить путь к папке
Третий Создайте пустой файл с именем init .py в вашем подкаталоге (это говорит Python, что это модуль)
Четвертый импорт модуля в папку
Ваша проблема в том, что Python ищет этот файл в каталоге Python и не находит его. Вы должны указать, что вы говорите о каталоге, в котором вы находитесь, а не о Python.
Для этого вы меняете это:
из application.app.folder.file import func_name
к этому:
Добавляя точку, вы говорите, ищите в этой папке папку приложения, а не в каталоге Python.
Ответы здесь не ясны, это проверено на Python 3.6
С этой структурой папок:
Где
myfile.py
имеет содержимое:Заявление об импорте в
main.py
:и это напечатает привет .
Из того, что я знаю, добавьте файл
__init__.py
непосредственно в папку функций, которые вы хотите импортировать, выполните эту работу.Рассматривая
application
в качестве корневого каталога для вашего проекта python, создайте пустой файл__init__.py
в папкахapplication
,app
иfolder
. Затем в вашемsome_file.py
внесите следующие изменения, чтобы получить определение func_name:Работал на меня в python3 на Linux
Я столкнулся с одной и той же проблемой, особенно при импорте нескольких файлов, именно так мне удалось ее преодолеть.
Попробуйте относительный импорт Python:
Каждая ведущая точка - это еще один более высокий уровень в иерархии, начинающийся с текущего каталога.
Проблемы? Если это не работает для вас, то вы, вероятно, получаете немного от относительного импорта многих гочей. Читайте ответы и комментарии для более подробной информации: https://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py
Подсказка: имейте
__init__.py
на каждом уровне каталогов. Вам может понадобитьсяpython -m application.app2.some_folder.some_file
(оставляя .py), который вы запускаете из каталога верхнего уровня, или каталог верхнего уровня в вашем PYTHONPATH. Фу!В Python 3.4 и более поздних версиях вы можете импортировать из исходного файла напрямую (ссылка на документацию). Это не самое простое решение, но я включаю этот ответ для полноты.
Вот пример. Сначала импортируемый файл с именем
foo.py
:Код, который импортирует файл выше, вдохновленный примером в документации:
Выход:
Обратите внимание, что имя переменной, имя модуля и имя файла не должны совпадать. Этот код все еще работает:
Выход:
Программно импортирующие модули были представлены в Python 3.1 и дают вам больше контроля над тем, как импортируются модули. Обратитесь к документации для получения дополнительной информации.
Использование sys.path.append с абсолютным путем не идеально при перемещении приложения в другие среды. Использование относительного пути не всегда работает, потому что текущий рабочий каталог зависит от того, как был вызван скрипт.
Поскольку структура папок приложения исправлена, мы можем использовать os.path, чтобы получить полный путь к модулю, который мы хотим импортировать. Например, если это структура:
И скажем, что вы хотите импортировать модуль «Манго». Вы можете сделать следующее на vanil.py:
Конечно, вам не нужна переменная mango_dir.
Чтобы понять, как это работает, посмотрите на этот интерактивный сеанс пример:
И проверьте документацию os.path.
Это работает для меня на окнах
Я особенный: я использую Python с Windows !
Я просто заполняю информацию: как для Windows, так и для Linux относительный и абсолютный путь работают в `sys.path '(мне нужны относительные пути, потому что я использую свои сценарии на нескольких ПК и в разных основных каталогах).
И при использовании Windows
\
и/
можно использовать в качестве разделителя для имен файлов, и, конечно, вы должны удвоить\
в строки Python некоторые действительные примеры:(примечание: я думаю, что
/
удобнее, чем\
, событие, если оно менее «уроженно Windows», потому что оно совместимо с Linux и проще для записи и копирования в проводник Windows)Если целью загрузки модуля с определенного пути является помощь вам во время разработки пользовательского модуля, вы можете создать символическую ссылку в той же папке тестового скрипта, которая указывает на корень пользовательского модуля. Эта ссылка на модуль будет иметь приоритет над любыми другими модулями, установленными с тем же именем для любого скрипта, запущенного в этой папке.
Я тестировал это на Linux, но он должен работать в любой современной ОС, которая поддерживает символические ссылки.
Одним из преимуществ этого подхода является то, что вы можете указать на модуль, который находится в вашей собственной рабочей копии локальной ветви SVC, что может значительно упростить время цикла разработки и уменьшить режимы отказа при управлении различными версиями модуля.
Я работал над проектом
a
, который я хотел, чтобы пользователи устанавливали черезpip install a
со следующим списком файлов:setup.py
MANIFEST.in
a / init.py
а / а.пи
a / b / init.py
а / б / б.пи
Я установил модуль, запустив следующее из каталога с
MANIFEST.in
:Затем из совершенно другого места в моей файловой системе
/ усы / армрестл
я смог запустить:Это подтвердило, что «a.cats» действительно равнялся 0, а «a.b.dogs» действительно равнялся 1, как предполагалось.
В моем случае у меня был класс для импорта. Мой файл выглядел так:
В мой основной файл я включил код через:
Вы можете использовать importlib для импорта модулей, в которых вы хотите импортировать модуль из папки, используя строку, например:
В этом примере есть main.py, который является вышеуказанным кодом, затем папка Scripts, и вы можете вызвать все, что вам нужно, из этой папки, изменив переменную
scriptName
. Затем вы можете использоватьscript
для ссылки на этот модуль. например, если у меня есть функцияHello ()
в модуле Snake, вы можете запустить эту функцию, выполнив это:Я проверил это в Python 3.6