ошибка импорта cython в том же пакете

Я видел этот вопрос, и ответ, похоже, не работает. Ниже приведена моя структура каталогов.

.
├── my_package
│   ├── a.pyx
│   ├── b.pyx
│   ├── b.pxd
│   ├── test.py
│   └── __init__.py
└── setup.py

файл .pyx

cimport my_package.b  as b

class a:
    def __init__(self):
        self.b = b.b()
        self.b.run()

файл b.pyx

cdef class b:

    def __init__(self):
        pass

    cpdef run(self):
        print "b is running"

файл b.pxd

cdef class b:
    cpdef run(self)

test.py

import a

c = a.a()

setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy

extensions = [
    Extension("my_package.a", ["my_package/a.pyx"]
        ),
    Extension("my_package.b", ["my_package/b.pyx"]
)
]

for e in extensions:
    e.cython_directives = {"embedsignature": True}

setup(
    name = "preprocess",
    ext_modules = cythonize(extensions),
)

после запуска python setup.py build_ext --inplace ошибки компиляции нет. Но если я попытаюсь запустить test.py, он выдаст ImportError: No module named my_package.b.

Любой вклад будет оценен.

Кстати, если мы изменим первую строку a.pyx с cimport my_package.b as b на import b, это сработает.


person user2660324    schedule 24.05.2018    source источник


Ответы (1)


Чтобы cimport подпакета работало, каталог пакета должен содержать файл __init__.pxd.

Это эквивалент __init__.py для cimport вместо import.

Сделайте структуру каталогов такой:

.
├── my_package
│   ├── a.pyx
│   ├── b.pyx
│   ├── b.pxd
│   ├── test.py
│   └── __init__.py
│   └── __init__.pxd
└── setup.py

Затем включите файлы pxd в качестве данных пакета в setup.py, чтобы они были установлены:

from setuptools import setup, Extension
from Cython.Build import cythonize

extensions = [
    Extension("my_package.a", ["my_package/a.pyx"]
        ),
    Extension("my_package.b", ["my_package/b.pyx"]
)
]

for e in extensions:
    e.cython_directives = {"embedsignature": True}

package_data = {'my_package': ['*.pxd']}

setup(
    name = "preprocess",
    ext_modules = cythonize(extensions),
    include_package_data=True,
    package_data=package_data,
)

Примечание. import numpy не должно быть в setup.py, так как установка пакета не будет работать, если numpy уже не установлен.

Поместите его в requirements.txt, чтобы он был установлен вместе с пакетом.

person danny    schedule 25.05.2018
comment
Здравствуйте, спасибо за ответ, у меня еще остались вопросы. 1. Я получаю Unknown distribution option: 'include_package_data' после попытки установки вашего setup.py. Я попытался установить python-distutils-extra (в Ubuntu 16.04), но предупреждение не сработало. 2. Я предполагаю, что init.pxd — это пустой файл, как и init.py? 3. Есть ли у вас какие-либо рекомендации, из которых я могу узнать? - person user2660324; 25.05.2018
comment
Обновлены - необходимо импортировать из setuptools и, возможно, также обновить setuptools. __init__.pxd должно быть пустым. документация по cython довольно хороша, хотя и не охватывает всего. Обучение через действие работает хорошо. - person danny; 29.05.2018