Например, Моя Структура проекта выглядит так:
Project:
├── package
│ ├── __init__.py
│ ├── utils
│ │ ├── __init__.py
│ │ ├── sample.py
│ │ └── ...
│ ├── lib
│ │ ├── __init__.py
│ │ ├── sample.py
│ │ └── ...
│ ├── scripts.py
│ └── ...
├── test
│ ├── test_utils.py
│ └── test_lib.py
└── run.py
В test_utils.py
я должен импортировать utils
на from package import utils
или from ..package import utils
.
Но с первым вариантом, если я не добавлю package
к sys.path
, ModuleNotFoundError
произойдет, когда я запусту python test_utils.py
, взяв Project\test
в качестве root exc dir.
# Project\test\test_utils.py
from package import utiils
# ... other operations
Другой метод заключается в использовании python run.py
для запуска модуля в родительской папке, где sys.path
содержит package
.
# Project\test\test_utils.py
from package import utiils
# ... other operations
# Project\tun.py
from test import test_util
# ... other operations
И второе, потому что точный корень - Project\test
(python test_utils.py
), поэтому он не может быть python package
. Таким образом, текущий каталог test_utils.py
, то есть Project\test
, становится пакетом верхнего уровня с ошибкой Attempted relative import beyond top-level package
, и мы не можем выйти за пределы родительского каталога с ..
.
# Project\test\test_utils.py
from ..package import utiils
#... other operations
В run.py
используйте from test.test_utils
, а затем python run.py
аналогично второму, также встретится attempted relative import beyond top-level package
Ошибка. Но разница в том, что во втором пакете верхнего уровня Project\test
меньше относительного пути к модулю ..
(относительно test_utils.py, который равен projct
). В то время как в run.py
они равны (оба Project
). Хорошее перемещение всего модуля, кроме run.py
, в родительский пакет большего размера может решить проблему.
# Project\test\test_utils.py
from ..package import utiils
#... other operations
# Project\run.py
from test import test_utiils
#... other operations
В заключение:
При использовании абсолютного импорта можно импортировать все модули, а также пакеты parellel to или ниже , чем exir-dir (текущий dir python x.py
). без добавления к sys.path
.
При использовании относительного импорта можно импортировать только модули и пакеты, содержащиеся в ниже пакета, чем в excute dir, поскольку мы не можем выйти за пределы пакета верхнего уровня.
Итак, мне интересно, существует ли изящный способ избежать этих раздражающих проблем, кроме добавления в sys.path
или перемещения в качестве подпакета?
И не могли бы вы объяснить более глубокую причину этих проблем?