Had a basic question after reading the Cython documentation on classes, but I thought to get it clear. Here is a sample code from the Cython documentation:
cdef class Rectangle:
cdef int x0, y0
cdef int x1, y1
def __init__(self, int x0, int y0, int x1, int y1):
self.x0 = x0; self.y0 = y0; self.x1 = x1; self.y1 = y1
cpdef int area(self):
cdef int area
area = (self.x1 - self.x0) * (self.y1 - self.y0)
if area < 0:
area = -area
return area
Why is the __init__
preceded by def
and not cdef
or cpdef
?
I realize that there is a __cinit__
function, but shouldn't making cpdef __init__
make the __init__
code faster?
Or, are we supposed to put the code, that we need to make very fast, in the __cinit__
section and the code, which we can afford to run slower, in the __init__
section?
cpdef
does not affect the speed of the code inside the function. It only creates a version of the function that can be called directly from C/Cython (without having to go through the Python call mechanism). The "inside" of the function is compiled in both cases and runs at exactly the same speed. See Definition of def, cdef and cpdef in cython for a full discussion.
Most Cython special functions (those with names of the form __xxx__
) are restricted to being defined as def
functions. Essentially because they serve a special purpose to the Python interpreter and Cython won't be able to use the C shortcut version. __init__
is no exception - it's part of the normal Python construction mechanism and so it only make senses to call it as a Python method.
__cinit__
is a slightly odd case - it can only be invoked by the Cython (implicitly) and cannot be called by the user. It therefore isn't really either a normal def
, cdef
or cpdef
method. It's therefore just a matter of language design what keyword is used to define it (whatever you chose, it'd always be called in the same way anyway). In terms of what arguments it accepts it behaves like a def
function though since it can handle *args
and **kwds
but only types that can be directly converted from Python objects (i.e. not C pointers).
If you can to make an alternate cdef
(or cpdef
) staticmethod
constructor to be called directly from Cython you can. This is discussed in the documentation.
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