这是我非常简单的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
..
有人可以帮我理解错误和问题是什么吗?
答案 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
代码将中断。