Быстрая версия:
Как объявить абстрактный класс в 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
Все красиво компилируется, но когда я импортирую impl.so
в питоне я получаю следующее:
ImportError: No module named interface
Видимо метод не был действительно виртуальным и Python хочет IModel
экземпляр
Больше деталей:
У меня есть класс расширения Cython (cdef class Integrator
) который должен работать в любом случае, реализуя IModel
интерфейс. Интерфейс просто гарантирует, что экземпляр имеет метод void get_dx(double[:] x, double[:] dx)
, так что интегратор может назвать это каждым шагом интеграции, чтобы, ну, в общем, интегрировать модель. Идея состоит в том, что можно реализовать различные модели в Cython, а затем в интерактивном режиме интегрировать их и построить результаты в питон скрипты. Как это:
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
lorenz.pyx
класс должен выглядеть примерно так:
from imodel cimport IModel
cdef class Lorenz(IModel):
cdef void get_dx(double[:] x, double[:] dx)
# implementation
И integrator.pyx
:
from imodel cimport IModel
cdef class Integrator:
cdef IModel model
def __init__(self, IModel model):
self.model = model
# rest of the implementation
В идеале IModel должен только существуют в виде определения класса в заголовок Cython файл (т.е. imodel.pxd), но до сих пор я мог достичь желаемой функциональности, только написав уродливый фиктивный класс реализации в imodel.pyx
, Хуже всего то, что эту бесполезную фиктивную реализацию нужно скомпилировать и связать, чтобы другие классы Cython могли наследовать от нее.
PS: Я думаю, что это идеальный вариант использования для абстрактных классов, однако, если вам, на самом деле, нехорошо, уважаемые программисты ООП, скажите, пожалуйста, какой другой подход я должен использовать.
Оказывается, это не совсем возможно (обсуждение). В настоящее время интерфейсы не поддерживаются, по-видимому, потому что они не имеют решающего значения: обычное наследование работает довольно хорошо.
Как объявить абстрактный класс в C ++
объявить нормальный класс, но этот класс должен иметь хотя бы одну чисто виртуальную функцию.
пример: класс abc {
virtual void show () = 0 // чистый виртуальный funcn.no defn вообще
}