Абстрактные классы (с чисто виртуальными методами) в Cython

Быстрая версия:
Как объявить абстрактный класс в 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: Я думаю, что это идеальный вариант использования для абстрактных классов, однако, если вам, на самом деле, нехорошо, уважаемые программисты ООП, скажите, пожалуйста, какой другой подход я должен использовать.

10

Решение

Оказывается, это не совсем возможно (обсуждение). В настоящее время интерфейсы не поддерживаются, по-видимому, потому что они не имеют решающего значения: обычное наследование работает довольно хорошо.

5

Другие решения

Как объявить абстрактный класс в C ++
объявить нормальный класс, но этот класс должен иметь хотя бы одну чисто виртуальную функцию.
пример: класс abc {
virtual void show () = 0 // чистый виртуальный funcn.no defn вообще
}

0

По вопросам рекламы [email protected]