在这个非常简单的cython程序中继续得到难以理解的错误

时间:2018-02-26 13:39:41

标签: python cython

这是我非常简单的cython程序。

test/__init__.py(空白文件)

test/__main__.py(主要档案)

from test.program import Program
Program.Main([])

test/program.pyx

from .example import *
from .example cimport *

class Program:
    @staticmethod
    def Main(args):
        h = ExampleClass()
        h.SayHi()

test/example.pyx

cdef class ExampleClass:
    cdef SayHi(self):
        print("HI")

test/example.pxd

cdef class ExampleClass:
    cdef SayHi(self)

如果我按py36 test/__main__.py运行此程序,程序会输出这个难以理解的错误..

Traceback (most recent call last):
  File "test\__main__.py", line 1, in <module>
    from test.program import Program
  File "test\program.pyx", line 1, in init test.program
    from .example import *
TypeError: Cannot overwrite C type ExampleClass

如果我修改代码

from .example import *
from .example cimport *

以下代码块之一

from .example import ExampleClass
from .example cimport *

from .example import *
from .example cimport ExampleClass

from .example import ExampleClass
from .example cimport ExampleClass

,错误消失,程序运行良好,没有错误。

我无法理解为什么原始的未经修改的代码会输出奇怪的TypeError: Cannot overwrite C Type ExampleClass .. 有人可以帮我理解错误和问题是什么吗?

1 个答案:

答案 0 :(得分:0)

program.pyx中,使用Python模块和Cython导入。

编译example.pyx代码后,ExampleClass已被定义为本机类型。

然后python级别导入指示python解释器加载包含ExampleClass本机类型的python模块 - 注意,而不是它的Cython定义,而是运行时python模块。

由于Cython已经在编译时使用a fixed definition声明了该类型,因此它被视为重新声明本机类型的尝试。这就是TypeError: Cannot overwrite C type ExampleClass的含义。

换句话说,python级别导入试图重新声明静态定义的C扩展类,这是Cython不允许的。

简而言之,从from .example import <..>文件中删除.pyx行。

仅当只有Python时才需要Python级别导入,如常规.py文件和仅需要使用Cython的声明 - 这不是上述情况。

作为旁注,Cython的cimport不支持相对导入,也最好不要使用*进行导入。当作为包安装时,相对cimport代码将中断。