5

Cythonのデフォルトコンストラクターの使用に問題があります。

私のC++クラスノードは次のとおりです

Node.h

class Node
{
public:
    Node()
    { 
        std::cerr << "calling no arg constructor" << std::endl;
            w=0.0;
        d=0.0;
    }
    Node(double val, double val2);
    {
            std::cerr << "calling 2 args constructor" << std::endl;
        this->w=val;
        this->d=val2;
    }
private:
    double d,w;
}

次のようにCythonでラップされています

cdef extern from "Node.h":
    cdef cppclass Node:
        Node() except +
        Node(double val1, double val2) except +
        double d
        double w

cdef class pyNode:
    cdef Node *thisptr      # hold a C++ instance which we're wrapping

    def __cinit__(self):
        self.thisptr = new Node()

    def __cinit__(self, double val1, double val2):
        self.thisptr = new Node(val1,val2)

    def __dealloc__(self):
        del self.thisptr

    def __repr__(self):
        return "d=%s w=%s" % (self.thisptr.w, self.thisptr.w )

Cythonコードはうまくコンパイルされますが、特にPythonから呼び出された場合

from pyNode import pyNode as Node
n=Node(1.0,2.0)

期待されるcalling 2 args constructor文字列を取得しましたが、「引数なし」コンストラクターを使用してPythonからNodeオブジェクトを宣言しようとすると(__cinit__(self)出力が得られないため、正しく宣言する必要があります。これは、引数なしコンストラクターが呼ばれていません!

ラップされたクラスのcinitメソッドから明示的に呼び出すにはどうすればよいですか?

4

1 に答える 1

10

ここでの問題は、その__cinit__()ようにオーバーロードできないことです (関数のみcdefをオーバーロードできるため)。代わりに、デフォルト値を取得してから、必要に応じて正しいものを呼び出します。

編集: 基本的に、オーバーロードを使用する代わりに、通常の Python コードで行う方法に近い方法で関数を実装する必要があります。

def __cinit__(self, double val1=-1, double val2=-1): 
    if val1 == -1 or val2 == -1:
        self.thisptr = new Node()
    else:
        self.thisptr = new Node(val1,val2)

当然、これは-1関数にとって役に立たない値であると仮定します。別の値を使用することもできます。または、double のすべての値を有効にする必要がある場合は、型を削除して Python オブジェクトを取得する必要があるかもしれません。デフォルトとして使用できNoneます:

def __cinit__(self, val1=None, val2=None):
    if val1 is not None and val2 is not None:
        self.thisptr = new Node(val1, val2)
    else:
        self.thisptr = new Node()
于 2012-11-02T19:41:20.313 に答える