Как импортировать модуль расширения python, который имеет то же имя, что и чистый пакет python с подпакетами и модулями?

У меня есть проект с модулями расширения pybind11, структурированный иерархически.

При импорте столкнулся со следующей проблемой:

1. Тест 1

1.1. Структура пакета

org
├── __init__.py
├── sdk
│   ├── core.cpython-37m-x86_64-linux-gnu.so
│   └── __init__.py
└── sdk.cpython-37m-x86_64-linux-gnu.so

1.2. Тип импорта из модуля org.sdk:

python -c "from org.sdk import CommonType"
1.2.1. Fails with the error:
ImportError: cannot import name 'CommonType' from 'org.sdk' (python3.7/site-packages/org_sdk-0.0.0-py3.7-linux-x86_64.egg/org/sdk/__init__.py)

1.3. Тип импорта из модуля org.sdk.core:

python -c "from org.sdk.core import A"
1.3.1. Success

2. Тест 2

Удалено org/sdk/__init__.py

2.1. Структура пакета

org
├── __init__.py
├── sdk
│   └── core.cpython-37m-x86_64-linux-gnu.so
└── sdk.cpython-37m-x86_64-linux-gnu.so

2.2. Тип импорта из модуля org.sdk:

python -c "from org.sdk import CommonType"
2.2.1. Success

2.3. Тип импорта из модуля org.sdk.core:

python -c "from org.sdk.core import A"
2.3.1. Fails with the error:
ModuleNotFoundError: No module named 'org.sdk.core'; 'org.sdk' is not a package

Я хотел бы знать, как мне найти решение, при котором оба импорта будут работать?

Кажется, что загрузчик Python по умолчанию предпочитает org/sdk/__init__.py для загрузки пакета org.sdk, возможно ли добавить некоторый код в org/sdk/init.py, который также загружал бы модуль расширения pybind11 org/sdk.cpython-37m-x86_64-linux-gnu.so?


person Mário Costa    schedule 02.05.2019    source источник


Ответы (1)


Обычная практика смешивания python и C++ в одном пакете состоит в том, чтобы назвать модуль чистого C++ с подчеркиванием в начале и импортировать из него в модуль python.

Макет будет выглядеть так:

org
├── __init__.py
└── sdk
    ├── __init__.py # import ._core as core
    └── _core.cpython-37m-x86_64-linux-gnu.so
person Sergei    schedule 12.05.2019