Импорт напрямую из пакета пространства имен в setuptools
Как использовать модуль как в качестве пакета пространства имен, так и в качестве контейнера для классов в конкретном подпроекте? То есть как я могу импортировать что-то непосредственно из пакета пространства имен вместо его подпакетов?
Пример может прояснить вопрос.
Три подпакета calc
Предположим, я хочу создать пакет пространства имен calc
и есть три проекта ( sscce: calcs.tar.gz). Первый найден на calc-add
каталог, имеет следующую структуру:
calc-add/calc/
calc-add/calc/add.py
calc-add/calc/__init__.py
Содержание calc-add/calc/__init__.py
просто
__import__('pkg_resources').declare_namespace(__name__)
в соответствии с требованиями пакетов пространства имен, и add.py
имеет только следующую функцию:
def op(n1, n2):
return n1 + n2
Есть еще один проект, на calc-sub
каталог, имеет следующую структуру:
calc-sub/calc/
calc-sub/calc/sub.py
calc-sub/calc/__init__.py
__init__.py
файл идентичен предыдущему и sub.py
имеет только простую функцию:
def op(n1, n2):
return n1 - n2
Наконец, у меня есть calc-main
каталог со следующим содержанием:
calc-main/calc/
calc-main/calc/main.py
calc-main/calc/__init__.py
Опять же, __init__.py
имеет только упомянутую строку, пока main.py
имеет следующий код:
import calc.add, calc.sub
def apply(n1, n2, op):
if op == "add":
return calc.add.op(n1, n2)
else:
return calc.sub.op(n1, n2)
Как мне позвонить и как мне позвонить apply()
функция
Если я вызову интерпретатор Python с $PYTHONPATH
установить как показано ниже:
$ PYTHONPATH=$PYTHONPATH:../calc-add/:../calc-sub/ python
тогда я могу позвонить apply()
сюда:
>>> import calc.main
>>> calc.main.apply(2, 3, 'add')
5
Тем не менее, я хотел бы позвонить apply()
прямо из calc
, как показано ниже:
>>> import calc
>>> calc.apply(2, 3, 'add')
5
Это, очевидно, работает, если я добавлю следующую строку в calc-main/calc/__init__.py
:
from main import apply
Однако документация по setuptools предельно ясна:
Вы НЕ ДОЛЖНЫ включать какой-либо другой код и данные в пакет __init__.py пакета пространства имен. Несмотря на то, что он может работать во время разработки или когда проекты установлены как файлы.egg, он не будет работать, если проекты установлены с использованием "системных" инструментов упаковки - в таких случаях файлы __init__.py не будут установлены, не говоря уже о казни.
Так как я могу получить то, что я хочу, не нарушая ограничения на __init__.py
файлы? Это возможно?