简体   繁体   English

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

[英]Cython: using imported class in a type declaration

I'm writing a Cython 0.23 program, and I can't figure out how to use a cdef class that I import from a different module in a type declaration. 我正在编写一个Cython 0.23程序,我无法弄清楚如何使用从类型声明中的不同模块导入的cdef class Here is a snippet that reproduces the problem. 这是一个重现问题的片段。

test.py : test.py

import pyximport
pyximport.install()

from mymodule import *

obj = MyClass(42)
print(obj.field)
print(identity(obj).field)

This works as expected and prints 42 twice: 这按预期工作,并打印42次:

mymodule.pyx : mymodule.pyx

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

cpdef MyClass identity(MyClass obj):
    return obj

This fails with a compiler error: 这会因编译器错误而失败:

mymodule.pyx : mymodule.pyx

from utils import MyClass

cpdef MyClass identity(MyClass obj):
    return obj

utils.pyx : utils.pyx

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

The error: 错误:

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):
                      ^
------------------------------------------------------------

The project I need this for is small and I can refactor it so that I don't need to import the class, but this solution doesn't look very clean. 我需要的项目很小,我可以重构它,这样我就不需要导入类了,但是这个解决方案看起来不是很干净。 Is there a better way? 有没有更好的办法?

You need to use a declaration ".pxd" file and cimport . 您需要使用声明“.pxd”文件cimport (Essentially, cimport happens at compile time, while import happens at run time so Cython can't make use of anything imported). (基本上, cimport发生在编译时,而import发生在运行时,因此Cython不能使用任何导入的东西)。

Create "utils.pxd": 创建“utils.pxd”:

cdef class MyClass:
    cdef readonly int field

"utils.pyx" now reads “utils.pyx”现在读了

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

(ie remove the declaration of field since it's specified in the .pxd file). (即删除field声明,因为它在.pxd文件中指定)。

Then in mymodule.pyx 然后在mymodule.pyx

from utils cimport MyClass
# other code follows...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM