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.
Discussione pertinente sulla mailing list 'cython-devel': https: //mail.python.org/pipermail/cython-devel/2014-January/003899.html –