Quick version: How to declare an abstract class in Cython? The goal is to declare interface only, so that other classes can inherit from it, there must be no implementation of this class.
interface.pxd:
cdef class IModel:
cdef void do_smth(self)
impl.pyx:
from interface cimport IModel
cdef class A(IModel):
cdef void do_smth(self):
pass
Everything nicely compiles, but when I'm importing impl.so
in python I get following:
ImportError: No module named interface
Apparently the method wasn't really virtual and python wants IModel
's instance
More details:
I have a cython extension class (cdef class Integrator
) which should operate on any instance, implementing the IModel
interface. The interface simply ensures that the instance have a method void get_dx(double[:] x, double[:] dx)
, so that integrator can call it every integration step in order to, well, integrate the model. The idea is that one can implement different models in cython and then interactively integrate them and plot the reults in python scripts. Like that:
from integrator import Integrator # <-- pre-compiled .so extension
from models import Lorenz # <-- also pre-compiled one, which inherits
# from IModel
mod = Lorenz()
i = Inegrator(mod)
i.integrate() # this one's really fast cuz no python is used inside
# do something with data from i
The lorenz.pyx
class should look something like:
from imodel cimport IModel
cdef class Lorenz(IModel):
cdef void get_dx(double[:] x, double[:] dx)
# implementation
And the integrator.pyx
:
from imodel cimport IModel
cdef class Integrator:
cdef IModel model
def __init__(self, IModel model):
self.model = model
# rest of the implementation
Ideally, IModel should only exist in the form of a class definition in a cython header file (i.e. imodel.pxd), but so far I could only achieve the desired functionality by writing an ugly dummy implementation class in imodel.pyx
. The worst thing is that this useless dummy implementation has to be compiled and linked so that other cython classes can inherit from it.
PS: I think this is a perfect use case for abstract classes, however, if it in fact looks bad to you, dear OOP coders, please tell me which other approach shall I use.
It turns out that it's not quite possible (discussion). Currently, interfaces are not supported, apparently because they are not of a critical importance: usual inheritance works quite good.
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