[英]Cython and constructors of classes
I have a problem with Cython usage of default constructors. 我对默认构造函数的Cython使用有疑问。
My C++ class Node is the following 我的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;
}
is wrapped in Cython as follows 包裹在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 )
The Cython code compiles well, but in particular when called from Python Cython代码编译良好,但特别是从Python调用时
from pyNode import pyNode as Node
n=Node(1.0,2.0)
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! 我得到了预期的
calling 2 args constructor
字符串,但是如果我尝试使用“ no-arguments”构造函数(应该正确地声明为__cinit__(self)
从python声明一个Node对象,则没有任何输出,这表示不调用无参数构造函数!
How can I explicitly call it from the cinit method of the wrapped class? 如何从包装类的cinit方法显式调用它?
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. 这里的问题是您不能像这样重载
__cinit__()
(因为只能重载cdef
函数 )-而是让它采用默认值,然后根据需要调用正确的东西。
Edit: Essentially, you need to implement the function in a way closer to how you would in normal Python code, instead of using overloading: 编辑:从本质上讲,您需要以一种接近于普通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)
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: 自然地,假定
-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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.