Как импортировать модуль расширения Python, который имеет то же имя, что и чистый пакет Python, с подпакетами и модулями? - PullRequest
2 голосов
/ 02 мая 2019

У меня есть проект с модулями расширения 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.Сбой с ошибкой:
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.Успех

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.Успех

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

python -c "from org.sdk.core import A"
2.3.1.Сбой с ошибкой:
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?

1 Ответ

0 голосов
/ 12 мая 2019

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

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

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