Не удается импортировать цепочку 3 уровня python

У меня есть следующая структура папок на 3 уровнях: папка1 содержит папку1_1, которая снова содержит папку1_1_1. Теперь у нас есть файл .py в каждой папке (помимо «в этом.py», который, по-видимому, необходим, и, извините, я не знаю, как поместить эти две строки до и после).

folder1  
L __init__.py  
L file1.py  
L folder1_1  
  L __init__.py  
  L file1_1.py  
  L folder1_1_1  
    L __init__.py  
    L file1_1_1.py

Содержимое файла файл1.py

from folder1_1.file1_1 import Test1_1 as lvl2
class Test1:
    randomnumber = 1
    sum = randomnumber  + lvl2.sum
    print (sum)

файл1_1.py

from folder1_1_1.file1_1_1 import Test1_1_1 as lvl3
class Test1_1:
    somenumber = 1
    sum = somenumber + lvl3.someothernumber
    print (sum)

файл1_1_1.py

class Test1_1_1:
    someothernumber = 1

Таким образом, каждый файл импортируется из папки непосредственно ниже. Один шаг работает: Когда я запускаю file1_1.py, импорт из file1_1_1 работает нормально и дает желаемый результат (2)

Но импорт «2-го уровня» в файле1 не выполняется:

  File "c:\Users\DSCO\Documents\folder1\folder1_1\file1_1.py", line 1, in <module>
    from folder1_1_1.file1_1_1 import Test1_1_1 as lvl3
ModuleNotFoundError: No module named 'folder1_1_1'

Как я могу импортировать таким образом? Или мне нужно изменить порядок папок? В реальном коде эта структура довольно сильно связана с файлом1_1, имеющим множество операторов импорта, указывающих на файл1_1_1, который на самом деле представляет собой множество файлов. Вот почему отдельная подпапка (folder1_1_1) Я проверил несколько S.O. проблемы, но все они несколько разные, на мой взгляд.

спасибо, Пранав, я не мог понять, как это сделать

DISC-O 12.05.2022 22:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь может быть интересен ПКП 366, но в этом случае вам не нужен флаг -m. В вашем случае единственная разница заключается в импорте в папку1_1/файл1_1.py. Я импортирую, начиная с записи название, где он был запущен, поэтому folder1_1 включен. Вы также можете увидеть больше информации в этих ответах:

Самый близкий к вашему примеру, который работает:

файловое дерево

➜ tree
.
├── file1.py
└── folder1_1
    ├── __init__.py
    ├── file1_1.py
    └── folder1_1_1
        ├── __init__.py
        └── file1_1_1.py

файл1.py

#!/usr/bin/env python3
from folder1_1.file1_1 import Test1_1 as lvl2


class Test1:
    randomnumber = 1
    sum = randomnumber + lvl2.sum
    print(sum)


if __name__ == "__main__":
    t1 = Test1()

папка1_1/файл1_1.py

from folder1_1.folder1_1_1.file1_1_1 import Test1_1_1 as lvl3


class Test1_1:
    somenumber = 1
    sum = somenumber + lvl3.someothernumber
    print(sum)

папка1_1/папка1_1_1/файл1_1_1.py

class Test1_1_1:
    someothernumber = 1
    print(someothernumber)

Теперь, если вы запустите из верхней папки:

./file1.py

Это дает результат:

1
2
3

Поэтому я предполагаю, что основное правило заключается в том, что операторы импорта в модулях, которые сами импортируются (например, file1_1), должны модифицировать свои собственные операторы импорта, как если бы они вызывались из основного модуля, что делает невозможным их выполнение на их собственном уровне. Мой файл1_1.py запустился сам по себе, больше нет. Но это нормально, работает!

DISC-O 13.05.2022 20:23

Да по существу. По крайней мере, это ожидаемая картина. Но есть много разных способов заставить вещи работать. Вы можете использовать относительный импорт или использовать модуль sys для изменения пути Python на лету по своему усмотрению.

theherk 13.05.2022 20:42

Другие вопросы по теме