Cython:在类型声明中使用导入的 class

Cython: using imported class in a type declaration

我正在编写 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):
                      ^
------------------------------------------------------------

我需要这个的项目很小,我可以重构它,这样我就不需要导入 class,但是这个解决方案看起来不太干净。有没有更好的方法?

您需要 use a declaration ".pxd" filecimport。 (本质上,cimport 发生在编译时,而 import 发生在 运行 时,因此 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...