Quick-Version: Wie deklariert man eine abstrakte Klasse in Cython? Das Ziel ist, nur die Schnittstelle zu deklarieren, so dass andere Klassen davon erben können, muss keine Implementierung dieser Klasse sein.Abstrakte Klassen (mit reinen virtuellen Methoden) in Cython
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
Alles schön kompiliert, aber wenn ich impl.so
in Python zu importieren bin ich bekomme folgende:
ImportError: No module named interface
Anscheinend war die Methode nicht wirklich virtuell und Python will IModel
‚s Instanz
Weitere Details:
ich eine cython Erweiterungsklasse haben (cdef class Integrator
), die auf jedem Fall arbeiten sollte, die IModel
Schnittstelle implementiert. Die Schnittstelle stellt lediglich sicher, dass die Instanz über eine Methode void get_dx(double[:] x, double[:] dx)
verfügt, so dass der Integrator sie bei jedem Integrationsschritt aufrufen kann, um das Modell zu integrieren. Die Idee ist, dass man verschiedene Modelle in Cython implementieren und diese dann interaktiv integrieren und die Ergebnisse in python Skripte plotten kann. Wie folgt aus:
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
Die lorenz.pyx
Klasse sollte etwas wie folgt aussehen:
from imodel cimport IModel
cdef class Lorenz(IModel):
cdef void get_dx(double[:] x, double[:] dx)
# implementation
Und die integrator.pyx
:
from imodel cimport IModel
cdef class Integrator:
cdef IModel model
def __init__(self, IModel model):
self.model = model
# rest of the implementation
Idealerweise IModel sollte nur existieren in Form einer Klasse Definition in einem Cython-Header Datei (dh imodel.pxd), aber so Bisher konnte ich die gewünschte Funktionalität nur durch Schreiben einer hässlichen Dummy-Implementierungsklasse in imodel.pyx
erreichen. Das Schlimmste ist, dass diese nutzlose Dummy-Implementierung kompiliert und verknüpft werden muss, damit andere Cython-Klassen davon erben können.
PS: Ich denke, das ist ein perfekter Anwendungsfall für abstrakte Klassen, aber wenn es dir schlecht aussieht, liebe OOP-Programmierer, sag mir bitte, welchen anderen Ansatz ich verwenden soll.
Relevante Diskussion auf der Mailingliste 'Cython-devel': https: //mail.python.org/pipermail/cython-devel/2014-Januar/003899.html –