Как импортировать из соседней директории
Структура проекта (условного):
example/
└── src/
├── a/
│ └── here.py
└── b/
└── importing.py
src/b/importing.py
def sqr(x): return x * x
Способов импорта sqr из src/b/importing.py в src/b/here.py много, но все они приводят в ошибкам.
from example.b.importing import sqr
Ошибка: No module named 'example'.
from ..b.importing import sqr
Ошибка: attempted relative import with no known parent package.
from b.importing import sqr
Ошибка: No module named 'b'.
Добавлял __init__.py во все возможные папки, удалял — ничего не менялось. Добавлял setup.py:
from setuptools import setup
setup(name='example', version='1.0.0', package_dir='src')
Также безуспешно.
Как сделать этот импорт?
Ответы (1 шт):
И так, структура проекта:
src\a\ init.py
from src.a.main_a import foo_a
# импорт делает функцию foo_a() доступной напрямую из src.a.main_a
src\b\ init.py
from src.b.main_b import foo_b
src\a\main_a.py
def foo_a():
print('С тобой говорит MAIN_A')
src\a\main_b.py
def foo_b():
print('С тобой говорит MAIN_B')
main.py
from src.a import foo_a
from src.b import foo_b
foo_a()
foo_b()
Что бы импортировать функцию из main_b.py в main_a.py:
main_a.py
from src.b import foo_Bb
foo_Bb()
src\b\ init.py
from src.b.main_b import foo_b
def foo_Bb():
foo_b()
Немного науки:
Абсолютный и относительный импорт При абсолютном импорте используется полный путь (от начала корневой папки проекта) к желаемому модулю.
При относительном импорте используется относительный путь (начиная с пути текущего модуля) к желаемому модулю. Есть два типа относительных импортов:
При явном импорте используется формат from .<модуль/пакет> import X, где символы точки . показывают, на сколько директорий «вверх» нужно подняться. Одна точка . показывает текущую директорию, две точки .. — на одну директорию выше и т. д. Неявный относительный импорт пишется так, как если бы текущая директория была частью sys.path. Такой тип импортов поддерживается только в Python 2. В документации Python об относительных импортах в Python 3 написано следующее:
Единственный приемлемый синтаксис для относительных импортов — from .[модуль] import [имя]. Все импорты, которые начинаются не с точки ., считаются абсолютными.
Источник: What’s New in Python 3.0
В качестве примера допустим, что мы запускаем start.py, который импортирует a1, который импортирует other, a2 и sa1. Тогда импорты в a1.py будут выглядеть следующим образом:
Абсолютные импорты:
import other
import packA.a2
import packA.subA.sa1
Явные относительные импорты:
import other
from . import a2
from .subA import sa1
Неявные относительные импорты (не поддерживаются в Python 3):
import other
import a2
import subA.sa1
Учтите, что в относительных импортах с помощью точек . можно дойти только до директории, содержащей запущенный из командной строки скрипт (не включительно). Таким образом, from .. import other не сработает в a1.py. В результате мы получим ошибку ValueError: attempted relative import beyond top-level package.
Как правило, абсолютные импорты предпочтительнее относительных. Они позволяют избежать путаницы между явными и неявными импортами. Кроме того, любой скрипт с явными относительными импортами нельзя запустить напрямую:
Имейте в виду, что относительные импорты основаны на имени текущего модуля. Так как имя главного модуля всегда "main", модули, которые должны использоваться как главный модуль приложения, должны всегда использовать абсолютные импорты.
Источник: Python 2 и Python 3

