2012-12-20 13 views
9

Versione rapida: Come dichiarare una classe astratta in Cython? L'obiettivo è dichiarare solo l'interfaccia, in modo che altre classi possano ereditarlo, ci deve essere nessuna implementazione di questa classe.Classi astratte (con metodi virtuali puri) 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 

Tutto ben compila, ma quando sto importazione impl.so in python ottengo seguente:

ImportError: No module named interface 

Apparentemente il metodo non era realmente virtuale e pitone vuole IModel 's esempio

Maggiori dettagli:

Ho una classe estensione Cython (cdef class Integrator), che dovrebbe operare su qualsiasi istanza, implementando l'interfaccia IModel. L'interfaccia garantisce semplicemente che l'istanza abbia un metodo void get_dx(double[:] x, double[:] dx), in modo che l'integratore possa chiamarlo ogni passo di integrazione per poter integrare il modello. L'idea è che si possano implementare diversi modelli in cython e quindi integrarli in modo interattivo e tracciare i reults negli script python. Come quella:

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 

Il lorenz.pyx classe dovrebbe essere simile:

from imodel cimport IModel 

cdef class Lorenz(IModel): 
    cdef void get_dx(double[:] x, double[:] dx) 
     # implementation 

E il integrator.pyx:

from imodel cimport IModel 

cdef class Integrator: 
    cdef IModel model 

    def __init__(self, IModel model): 
     self.model = model 

    # rest of the implementation 

Idealmente, IModel dovrebbe solo esistere sotto forma di una classe definizione in cython header file (cioè imodel.pxd), ma così Finora ho potuto ottenere la funzionalità desiderata solo scrivendo una brutta classe di implementazione fittizia in imodel.pyx. La cosa peggiore è che questa implementazione fittizia inutile deve essere compilata e collegata in modo che altre classi cython possano ereditarsene.

PS: Penso che questo sia un caso d'uso perfetto per le classi astratte, tuttavia, se in effetti ti sembra male, caro coder OOP, per favore dimmi quale altro approccio dovrei usare.

+2

Discussione pertinente sulla mailing list 'cython-devel': https: //mail.python.org/pipermail/cython-devel/2014-January/003899.html –

risposta

4

Si scopre che non è del tutto possibile (discussion). Attualmente, le interfacce non sono supportate, apparentemente perché non hanno un'importanza critica: l'ereditarietà abituale funziona piuttosto bene.

0

Come dichiarare una classe astratta in C++ dichiarare la classe normale ma quella classe deve avere almeno una funzione virtuale pura. es: class abc { virtual void show() = 0 // puro defn funcn.no virtuale a tutti }

+3

Esatto. Il problema è che non è possibile farlo in Cython – dmytro