2012-12-20 73 views
9

快速版: 如何在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 

一切很好的編譯,但是當我在python進口impl.so我得到以下幾點:

ImportError: No module named interface 

顯然這個方法並不是真的虛擬和python希望IModel的實例

更多細節:

我有一個用Cython擴展類(cdef class Integrator),它應該在任何情況下進行操作,實現IModel接口。界面只是確保實例有一個方法void get_dx(double[:] x, double[:] dx),以便集成者可以在每個集成步驟中調用它,以便集成模型。這個想法是,你可以在cython中實現不同的模型,然後以交互方式整合它們並在python腳本中繪製reults。這樣的:

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中的一個醜陋的dummy實現類來實現所需的功能。最糟糕的是,這個無用的虛擬實現必須被編譯和鏈接,以便其他的cython類可以繼承它。

PS:我認爲這是一個抽象類的完美用例,但是,如果它實際上對你不利,親愛的OOP編碼器,請告訴我應該使用哪種方法。

+2

關於'cython-devel'郵件列表的相關討論:https://mail.python。org/pipermail/cython-devel/2014-January/003899.html –

回答

4

事實證明,這不是完全可能的(discussion)。目前,接口不受支持,顯然是因爲它們並不重要:通常的繼承工作非常好。

0

如何聲明C++中的抽象類 聲明普通類,但該類必須至少有一個純虛函數。 例如:ABC類{ 虛擬無效秀()=所有 0 //純虛funcn.no DEFN}

+3

沒錯。問題是在Cython中不可能這樣做 – dmytro