2

我已经看到了这个问题,但答案似乎不起作用。以下是我的目录结构。

.
├── 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)

测试.py

import a

c = a.a()

安装程序.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 bimport b它将起作用。

4

1 回答 1

2

为了cimport使子包工作,包目录需要包含一个__init__.pxd.

它相当于__init__.pyforcimport而不是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与软件包一起安装。

于 2018-05-25T09:23:36.613 回答