In this post, we will see how to resolve How can I extend a built-in type in cython?
Question:I’m trying to extend the basic float in python with cython additional methods. I have a python implementation and I know I could create my own extended type by keeping an internal float value. But I’m trying to keep the same code base for interpreted and compiled code using the benefits of pure python mode.
So how can this be translated into cython?
__new__can’t be used in cython extended types. As far as I know
__cinit__is not appropriate because its not meant to return an instance.
The manual mentions that it is possible, although an extern would have to be declared. But I have not been able to find any examples of how this could be done.
Any help? Thanks!
Not only does Ahmed AEK’s answer below works. But there is a performance penalty
Yet adding two of instances is 10% slower than adding two instances of a cython class that stores its float value in an attribute, rather than subclassing float. (445ns for CythonFloatSubclass vs 400ns)
Even more worryingly, the interpreted python version of a class that holds a float value is faster than the cclass version of the same thing. (375ns)
To answer the comments: There will be more methods. In fact the main one is substraction, that instantiates a BearingDelta class, also a float subclass.
And the main concern is speed. I am simulating thousands of aicraft trajectories. I’ve concentrated on having a correct algorithm first, for which Bearing, BearingDelta, RangeBearing and Point classes help enormously even though they just substitute floats and tuples of floats. But now comes the optimization and with interpreted python it all becomes very slow because of all the instancing of new objects.
(I did a second edit because in my first test I was instancing the _CythonFloatSubclass in the
__add__method, which doesn’t go through the
__new__method of CythonFloatSubclass)
Best Answer:from the open issue on the problem
support __new__() in extension typeshttps://github.com/cython/cython/issues/799
it seems you cannot use the
__new__method in a cdef class, and have to use it in a wrapper python class.
If you have better answer, please add a comment about this, thank you!