我有一个现有的Python类X
,我想要做以下几件事:
from my_python_module import X
cdef class Y:
cdef X test
但是这并不能直接奏效,cdef 只能接受 C 类型,而不是 Python 类。有什么解决方法吗?
我认为你不能(http://docs.cython.org/src/userguide/sharing_declarations.html#sharing-extension-types),但你可以使用__cinit__
来绕过它,以确保属性具有正确的类型。扩展类型属性的声明cdef public object x
有以下含义:
cdef
用于声明Cython扩展类型的属性public
使得该属性可以从Python代码中访问object
是属性的类型,表示它是一个Python对象x
是该属性的标识符import my_python_module as q
cdef class Y:
cdef int i
cdef public object x # public so it can be accessed from Python
def __cinit__(self, x_):
assert isinstance(x_, q.X)
self.x = x_
如果您已经定义了类X,那么my_python_module.py
就是您定义该类的地方:
class X(object):
def __init__(self):
self.i = 1
import my_python_module as q
import p
y = p.Y(q.X())
print y.x
print y.x.i
另外需要注意的是,自 cython == 0.29.22
版本起,cpdef
和 cdef
的意思相同,并且在 cython == 3
中将不再支持(参见 Cython issue 3959,以及如果使用 cpdef
声明某个属性,则会打印出 warning that cython == 0.29.22
prints;还请参见该 Cython 版本的 changelog entry for that Cython version)。
cdef class SomeCls:
cdef object _x
def __cinit__(self, x_):
self._x = x_
property x:
def __get__(self):
return self._x
def __set__(self, x_):
self._x = x_
当公开外部结构体或类的属性时,上述方法特别有用。请参考此处的示例: 包装C ++
object
可以用来分配任何 Python 对象? - w00d