2012-12-20 7 views
9

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.

+2

Relevante Diskussion auf der Mailingliste 'Cython-devel': https: //mail.python.org/pipermail/cython-devel/2014-Januar/003899.html –

Antwort

4

Es stellt sich heraus, dass es nicht gut möglich ist (discussion). Derzeit werden Schnittstellen nicht unterstützt, offenbar weil sie keine kritische Bedeutung haben: Die übliche Vererbung funktioniert ziemlich gut.

0

Wie deklariert man eine abstrakte Klasse in C++ deklarieren normale Klasse, aber diese Klasse muss mindestens 1 rein virtuelle Funktion haben. ex: Klasse abc { virtual void show() = 0 // rein virtuelle funcn.no defn bei allen }

+3

Das stimmt. Das Problem ist, dass dies in Cython nicht möglich ist – dmytro

Verwandte Themen