Как сделать что бы модуль импортировал подмодули?
Как сделать чтобы модуль импортировал подмодули Python 3?
Есть например проект со структурой:
Смысл такой, я хочу при запуске GUI.py из папки report импортировать класс из report.py, который бы в свою очередь импортировал класс из calc_base.py из папки base_class. Он выдает ошибку "ModuleNotFoundError: No module named 'base_class'" Сам пример проекта прикрепляю ссылка на пример проекта
Да можно было бы вообще в одной папке все расположить =) Вопрос чисто технический , можно-ли так делать и делают ли так? И если можно сделать то как?
.дополнение_____ в файле calc_base.py из папки base_class есть класс
class Flow_rate:
def __init__(self, diametr_hole = 2000):
self.diametr_hole = diametr_hole
def flow_rate_liquid(self, diametr_hole = 200):
flow_rate_liquid = diametr_hole*2
return flow_rate_liquid
Который что бы импортировать на уровень выше в report.py папки report я использую init.py из папки base_class
from .calc_base import Flow_rate
Дальше в самом report.py я импортирую функцию из класса выше для использования ее в новой функции flow_str:
from base_class import Flow_rate
class Report:
def flow_str():
flow = Flow_rate().flow_rate_liquid(diametr_hole = 200)
flow_str = str(flow)+" Go!"
return flow_str
Вот до этого момента все нормально)
А вот когда я хочу по той же схеме через init.py папки report импортировать класс на уровень выше в GUI.py
from .report import Report
А самом GUI.py пишу
from report import Report
выдает ошибку: "ModuleNotFoundError: No module named 'base_class'" .
Т.е. я так понял он не собирает все init.py по пути.
Ответы (2 шт):
Дай Бог мне понять, что во что вложено... Буду ориентироваться по вашему описанию, а не по картинке. Если ошибусь, прошу прощения, надеюсь, смысл до вас смогу донести)
Если я не ошибаюсь, то модули = исполняемые коды, а не папки (хотя я могу ошибаться). Так что импортировать нужно именно коды, а не папки с ними.
Могу как решение вам предложить использовать изменение директории при помощи встроенного модуля os:
В итоге нужно будет записать такие выражения в файлах:
GUI.py:
import os #импортируем модуль для работы с системой
os.chdir('report') #изменяем действующую директорию на папку с нужным нам файлом для импорта
import report #импортируем нужный код: report.py
Аналогично в report.py:
import os
os.chdir('base_class') #переходим в папку base_class
import calc_base #импортируем calc_base.py
И давайте на засыпку объявим простую функцию в файле calc_base.py:
def func():
print('Hello world!')
Обратите внимание, что дабы это многоступенчатое импортирование пошло, вам нужно записать строки кода, приведённые выше, просто так. Без всякого
if __name__ == "__main__":
...
Импортируя, Питон как бы выполняет импортируемый код, отсюда и появляются классы и, в нашем случае, модули.
Теперь, допустим, вы открыли командную строку в директории с файлом GUI.py и решили импортировать его. Посмотрим, что выйдет:
командная строка:
C:\Users\User>python
>>> #строкой выше мы запустили питон в нашей директории для работы с ним непосредственно в настоящем времени
>>> import main #импортируем main, помня, что он импортирует report, который в свою очередь импортирует calc_base, в котором функция func()
>>> #теперь смотрите, как нужно вызвать нашу конечную функцию:
>>> main.report.calc_base.func()
Hello world!
>>> #то есть сначала обращаемся ко всему, что есть в main.py, путём "main.", включая наш report
>>> #далее обращаемся ко всему, что есть в report.py, путём "report.", включая calc_base и так далее, пока не добираемся до func()
То есть, как вы видите, мы можем сделать сколь-угодно-ступенчатую структуру, которая будет ссылаться друг к другу через точки.
К вопросу, используется ли это: честно говоря, больше 2 ступеней не встречал и те использовались лишь для кода ВНУТРИ модуля, а через сам модуль не вызывались. Зачем вызывать модуль через другой модуль, если можно попросту вызвать их по отдельности? Хотя может я просто не встречал. Безусловно красиво, но, как по мне, не совсем удобно.
Но как видите, если очень захотеть, можно и такое провернуть!
Всем добра-бобра и удачи в написании кода!
GUI.py
print("GUI.py")
from report.report import Report # report.py
report = Report()
flow_str = report.flow_str()
print(f'flow_str = {flow_str}')
report.py
from report.base_class.calc_base import Flow_rate # calc_base.py
print('report.py')
class Report:
def __init__(self): # +++
self.flow = Flow_rate() # +++
def flow_str(self): # +++ self !!!
# flow = Flow_rate().flow_rate_liquid(diametr_hole = 200)
flow = self.flow.flow_rate_liquid(diametr_hole = 300) # 300
flow_str = str(flow)+" Go!"
return flow_str
calc_base.py
print("calc_base.py")
class Flow_rate:
def __init__(self, diametr_hole=2000):
self.diametr_hole = diametr_hole
def flow_rate_liquid(self, diametr_hole=200):
flow_rate_liquid = diametr_hole * 2
return flow_rate_liquid
Спросите, если что-то будет не понятно.


