Cython和类的构造函数 [英] Cython and constructors of classes

查看:97
本文介绍了Cython和类的构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对默认构造函数的Cython使用有疑问。

I have a problem with Cython usage of default constructors.

我的C ++类Node是以下

My C++ class Node is the following

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包裹,如下所示:

is wrapped in Cython as follows

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调用时

The Cython code compiles well, but in particular when called from Python

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

我得到了预期的通话2 args构造函数字符串,但是如果我尝试使用 no-arguments构造函数(应正确声明为 __ cinit __(self)从Python声明一个Node对象我没有输出,这意味着不调用无参数构造函数!

I get the expected calling 2 args constructor string, but if I'm trying to declare a Node object from python using the "no-arguments" constructor (which should be correctly declared as __cinit__(self) I'm getting no output, this means that the no-argument constructor is not called!

如何从<包装的类的strong> cinit 方法?

推荐答案

这里的问题是您不能重载 __ cinit __()这样(如 cdef 函数可以重载)-而是使用默认值,然后根据需要调用正确的东西。

The issue here is that you can't overload __cinit__() like that (as only cdef functions can be overloaded) - instead, have it take default values, then call the right thing as needed.

编辑:本质上,您需要以与普通Python代码更接近的方式实现该功能,而不是使用重载:

Essentially, you need to implement the function in a way closer to how you would in normal Python code, instead of using overloading:

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 作为默认值:

Naturally, this presumes -1 is a value that isn't useful for the function, you could use another value, or if you need every value of a double to be valid, then you might need to remove the typing, taking a Python object so that you can use None as the default:

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()

这篇关于Cython和类的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆