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是一个对函数没有用的值,您可以使用另一个值,或者如果您需要双精度的每个值都有效,那么您可能需要删除类型,采用 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 回答