модуль импорта в разных контекстах

#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/')  

На случай, если у кого-то возникнет тот же вопрос и возникнет такая же борьба, как у меня.