I have a existing python class X
and I want to do the followings:
from my_python_module import X
cdef class Y:
cdef X test
But this does not work out of the box, the cdef only accepts C type, not a Python class. Any work-around ?
I don't think you can (http://docs.cython.org/src/userguide/sharing_declarations.html#sharing-extension-types) but you can work-around it using __cinit__
to assert that the attribute has the correct type. The declaration cdef public object x
of the extension type attribute has the following meaning:
cdef
is used to declare attributes of Cython extension types
public
makes the attribute accessible from Python code
object
is the type of the attribute, and means that it is a Python object
x
is the identifier of the attributeIn your Cython file (named "p.pyx" for example):
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_
and my_python_module.py
is where you have defined your class X:
class X(object):
def __init__(self):
self.i = 1
Then, you use it like this:
import my_python_module as q
import p
y = p.Y(q.X())
print y.x
print y.x.i
Also, note that cpdef
means the same as cdef
as of cython == 0.29.22
, and will not be supported in cython == 3
(Cython issue 3959, and the warning that cython == 0.29.22
prints if an attribute is declared with cpdef
; see also the changelog entry for that Cython version).
I would use something like this:
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_
The above is especially useful when exposing attributes of an extern struct or class. Refer to example here: wrapping C++
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With