Cython 相对导入错误,即使在进行绝对导入时也是如此

Cython relative import error, even when doing absolute import

我在 Cython(使用 Python 3.5)中遇到问题,无法在单个包中的模块之间导入。

我得到的错误是 SystemError: Parent module '' not loaded, cannot perform relative import,即使我显然在做绝对导入。

下面是我正在使用的一个简单的测试设置。使用下面的纯 Python 版本(.py 而不是 .pyx 并且没有编译),这很好用,但不是通过 Cython 编译的。请注意,在下面的示例中我实际上并没有使用任何 Cython 语言功能,只是编译。

我似乎对结构有些不正确?但我就是不知道如何让它正常工作。

文件结构:

PackageMain
 |
 +--__init__.py  (this is empty)
 +--PackageMain.pyx
 +--SomeModule.pyx
 +--setup.py

文件PackageMain.pyx

from PackageMain.SomeModule import SomeClass2  # get same error with relative import, ie just .SomeModule

class SomeClass1:
      def __init__(self):
          foo = SomeClass2()

文件SomeModule.pyx:

class SomeClass2:
      def __init__(self):
          print("Whoop!")

文件setup.py:

from distutils.core import setup, Extension
from Cython.Build import cythonize

extensions = [  Extension(language="c++", name="PackageMain",
                sources=["PackageMain.pyx", "SomeModule.pyx"])]

setup(  name = 'Some name',
        ext_modules = cythonize(extensions) )

运行 from PackageMain import PackageMain 使用 Cython 生成的 .pyd 文件然后导致上述错误。

使用以下代码/定义,

>>> from mytest import MainModule
>>> dir(MainModule)
['SomeClass1', 'SomeClass2', '__builtins__', '__doc__',
 '__file__', '__loader__', '__name__', '__package__', '__spec__', '__test__']

setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

extensions = [  Extension(language="c++",
                name="mytest.MainModule", sources=["mytest.MainModule.pyx"]),
                Extension(language="c++",
                name="mytest.SomeModule", sources=["mytest.SomeModule.pyx"])]

setup(  name = 'mytest',
        ext_modules = cythonize(extensions) )

mytest.MainModule.pyx

class SomeClass1:
      def __init__(self):
          foo = SomeClass2()

mytest.SomeModule.pyx

class SomeClass2:
      def __init__(self):
          print("Whoop!")

当 python 加载扩展模块 ABC 时,它期望找到一个名为 initABC 的函数,该函数将被调用以初始化模块。如果用cython生成的两个C++文件编译后放到同一个共享库中,则不会调用另一个Cython-based模块的init函数,也就找不到模块