我正在编写一个Cython 0.23程序,我无法弄清楚如何使用我在类型声明中从不同模块导入的cdef class
。这是一个重现问题的片段。
test.py
:
import pyximport
pyximport.install()
from mymodule import *
obj = MyClass(42)
print(obj.field)
print(identity(obj).field)
这可以按预期工作并打印42
两次:
mymodule.pyx
:
cdef class MyClass:
cdef readonly int field
def __init__(self, field):
self.field = field
cpdef MyClass identity(MyClass obj):
return obj
这会因编译错误而失败:
mymodule.pyx
:
from utils import MyClass
cpdef MyClass identity(MyClass obj):
return obj
utils.pyx
:
cdef class MyClass:
cdef readonly int field
def __init__(self, field):
self.field = field
错误:
Error compiling Cython file:
------------------------------------------------------------
...
from utils import MyClass
cpdef MyClass identity(MyClass obj):
^
------------------------------------------------------------
mymodule.pyx:3:6: 'MyClass' is not a type identifier
Error compiling Cython file:
------------------------------------------------------------
...
from utils import MyClass
cpdef MyClass identity(MyClass obj):
^
------------------------------------------------------------
我需要的项目很小,我可以重构它,这样我就不需要导入类了,但是这个解决方案看起来不太干净。还有更好的方法吗?
答案 0 :(得分:4)
您需要use a declaration ".pxd" file和cimport
。 (基本上,cimport
在编译时发生,而导入在运行时发生,因此Cython无法使用任何重要的东西。)
创建“utils.pxd”:
cdef class MyClass:
cdef readonly int field
“utils.pyx”现在读取
cdef class MyClass:
def __init__(self, field):
self.field = field
(即删除field
的声明,因为它在.pxd文件中指定。)
然后在mymodule.pyx
from utils cimport MyClass
# other code follows...