Я создаю утилиту Python, которую нужно будет совместно использовать внутри пакетов pip
, и которая будет использоваться как в виде библиотеки, так и в качестве инструмента командной строки.
У меня проблемы справильное использование пространств имен и где / когда / если поместить файлы __init__.py
для получения согласованной кодовой базы.
- Я могу заставить работать "библиотеку", поэтому я могу
from example_service.example import Example
. - Я могу заставить работать CLI, поэтому я могу выполнить
python example_service/example_cli.py
. - Я могу заставить работать
pytest
. - Я НЕ МОГУ заставить все три работать одновременно.
Итак
- Если мой пакет использует
from filename import Class
или from .filename
или from example_service.filename
? - Должен ли я поместить
__init__.py
в каталог пакета илине? Кажется, это не нужно для Python3, но я получаю смешанные результаты.
- Если
example.py
использует from componenta import ComponentA
и example_cli.py
использует from example import Example
- , тогда вызов CLI работает
- сбой импорта библиотеки с
no component named 'componenta'
- Если
example.py
использует from example_service.componenta import ComponentA
и example_cli.py
использует from example import Example
- , то вызов CLI завершится неудачно с
no component named 'example_service'
- импорт библиотеки работает
В настоящее время у меня есть каталог проекта, который выглядит что-токак это:
project_root/
example_service/
example.py
example_cli.py
componenta.py
componentb.py
tests/
__init__.py
test_example.py
setup.py
requirements.txt
Внутри моего основного кода lib, example.py
, у меня есть:
from componenta import ComponentA
class Example(object):
def foo(self):
a = ComponentA()
print("Example.foo()")
Моя оболочка CLI будет обрабатывать аргументы и прочее, но пока это просто:
#!/usr/bin/env python
from example import Example
class ExampleCli(object):
def __init__(self):
print("ExampleCli.init()")
e = Example()
e.foo()
if __name__ == '__main__':
ExampleCli()
И componenta.py
- это:
class ComponentA(object):
def bar(self):
print("ComponentA.bar()")
(полный код был отправлен на GitHub )