#python #python-import #python-module
Вопрос:
У меня есть файловая структура, подобная этой:
work/ ├─ analysis.ipynb ├─ app/ │ ├─ __init__.py │ ├─ class_a.py │ ├─ script.py │ ├─ utils.py
Файл class_a.py
содержит класс MyClass
, а также импорт из utils
такого:
from utils import useful_function class MyClass(): ...
Затем я пытаюсь импортировать MyClass
analysis.ipynb
вот так:
from app.class_a import MyClass
и получите сообщение об ошибке:
ModuleNotFoundError Traceback (most recent call last) lt;ipython-input-4-8eeb8559d767gt; in lt;modulegt; 2 import os 3 from datetime import datetime ----gt; 4 from app.class_a import MyClass 5 from app.utils import useful_function 6 ... ~/Documents/work/app/class_a.py in lt;modulegt; 1 import pandas as pd ----gt; 2 from utils import useful_function 3 4 class MyClass(): 5 '''indeed very necessary class for me ModuleNotFoundError: No module named 'utils'
Я понял, что если я изменю весь импорт в app
папке на что-то вроде этого:
from app.utils import useful_function
Тогда я смогу импортировать все, что мне нужно, из analysis.ipynb
Однако app
должно работать как то, с чем я работаю, python script.py
и это не работает, если импорт не написан оригинальным способом.
Я не разбираюсь в модулях и упаковке и поэтому даже не могу точно задать вопрос, но как мне выровнять импорт «стилей», чтобы можно было как запускать python scripts.py
из app
каталога, так и импортировать MyClass
из analys.ipynb
?
Комментарии:
1. Проблема в том, что если вы пишете
app.utils
, python пытается найтиutils
внутриapp
вложенной папки, которая не существует в контекстеclass_a
.2. @уайт, интуитивно я это понял. Я умею бегать script.py и analysis.py с некоторыми изменениями в коде. То, что я ищу, — это способ запустить их оба без этих изменений.
3. Вы можете использовать сценарий-оболочку, который управляет импортом. Снабдите его сценарием, который вы хотите запустить как параметр
python wrapper.py app
, и прочитайте параметр сsys.argv[1]
помощью . Таким образом, ваш контекст останется прежним.
Ответ №1:
import
операторы выполняют поиск по списку путей sys.path
, поэтому я добавил эти строки в свой analysis.ipynb
:
import sys sys.path.append('/path/to/work/app/')
На случай, если у кого-то возникнет тот же вопрос и возникнет такая же борьба, как у меня.