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

Pas*_*ist 8 python cython

我正在写一个Cython 0.23程序,我无法弄清楚如何使用cdef class我从类型声明中的不同模块导入的程序.这是一个重现问题的片段.

test.py:

import pyximport
pyximport.install()

from mymodule import *

obj = MyClass(42)
print(obj.field)
print(identity(obj).field)
Run Code Online (Sandbox Code Playgroud)

这按预期工作并打印42两次:

mymodule.pyx:

cdef class MyClass:
    cdef readonly int field
    def __init__(self, field):
        self.field = field

cpdef MyClass identity(MyClass obj):
    return obj
Run Code Online (Sandbox Code Playgroud)

这会因编译器错误而失败:

mymodule.pyx:

from utils import MyClass

cpdef MyClass identity(MyClass obj):
    return obj
Run Code Online (Sandbox Code Playgroud)

utils.pyx:

cdef class MyClass:
    cdef readonly int field
    def __init__(self, field):
        self.field = field
Run Code Online (Sandbox Code Playgroud)

错误:

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):
                      ^
------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*idW 5

您需要使用声明“ .pxd”文件cimport。(本质上,这cimport发生在编译时,而import发生在运行时,因此Cython无法使用任何导入的东西)。

创建“ utils.pxd”:

cdef class MyClass:
    cdef readonly int field
Run Code Online (Sandbox Code Playgroud)

“ utils.pyx”现在显示为

cdef class MyClass:
  def __init__(self, field):
    self.field = field
Run Code Online (Sandbox Code Playgroud)

(即删除声明,field因为它是在.pxd文件中指定的)。

然后在 mymodule.pyx

from utils cimport MyClass
# other code follows...
Run Code Online (Sandbox Code Playgroud)