12

クイックバージョン: 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スクリプトで結果をプロットできるというものです。そのように:

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)のクラス定義の形式でのみ存在する必要がありますが、これまでのところ、醜いダミーの実装クラスをで作成することによってのみ、目的の機能を実現できました。最悪のことは、他のcythonクラスがそれを継承できるように、この役に立たないダミーの実装をコンパイルしてリンクする必要があることです。imodel.pyx

PS:これは抽象クラスの完璧なユースケースだと思いますが、実際に悪いと思われる場合は、親愛なるOOPコーダーの皆さん、他にどのアプローチを使用するか教えてください。

4

2 に答える 2

6

それは完全には不可能であることが判明しました(議論)。現在、インターフェースはサポートされていません。これは、インターフェースがそれほど重要ではないためと思われます。通常の継承は非常にうまく機能します。

于 2012-12-24T00:20:51.140 に答える
0

C ++で抽象クラスを宣言する方法は通常のクラスを宣言しますが、そのクラスには少なくとも1つの純粋仮想関数が必要です。例:class abc {virtual void show()=0//純粋な仮想funcn.nodefnまったく}

于 2012-12-22T08:38:38.747 に答える