问题
我有一个基类LinkPredictor和一个子类KatzIndex ,它派生自C++ LinkPredictor 。 现在我有另一个类,它在构造函数中需要一个指向LinkPredictor的指针。
我想在Cython包装这些类,使它们在Python可用。
我的尝试
CPP:
class LinkPredictor { ... } class KatzIndex : public LinkPredictor { ... } class KFoldCrossValidator { public: KFoldCrossValidator(LinkPredictor* lp) { ... } }题
上面的方法不起作用。 Cython抛出以下错误消息:
Error compiling Cython file: ------------------------------------------------------------ ... cdef _KFoldCrossValidator* _this def __cinit__(self, LinkPredictor linkPredictor): self._this = new _KFoldCrossValidator(linkPredictor._this) ^ ------------------------------------------------------------ .../project.pyx:X:Y: Cannot convert Python object to '_LinkPredictor *'Problem
I have a base class LinkPredictor and a sub class KatzIndex which derives from LinkPredictor in C++. Now I have another class which needs in its constructor a pointer to a LinkPredictor.
I want to wrap those classes in Cython to make them available in Python.
My try
CPP:
class LinkPredictor { ... } class KatzIndex : public LinkPredictor { ... } class KFoldCrossValidator { public: KFoldCrossValidator(LinkPredictor* lp) { ... } }Question
The approach above is not working. Cython throws the following error message:
Error compiling Cython file: ------------------------------------------------------------ ... cdef _KFoldCrossValidator* _this def __cinit__(self, LinkPredictor linkPredictor): self._this = new _KFoldCrossValidator(linkPredictor._this) ^ ------------------------------------------------------------ .../project.pyx:X:Y: Cannot convert Python object to '_LinkPredictor *'I think this happens because as _this is only declared in KatzIndex it has the type _KatzIndex* instead of _LinkPredictor*. Now I tried to declare the inheritance-relationship from _LinkPredictor and _KatzIndex (by declaring _KatzIndex(_LinkPredictor)) and hoped that Cython would accept _this with type _LinkPredictor* as _KatzIndex derives from _LinkPredictor. But that doesn't seem to be the case.
What are your thoughts on this?
最满意答案
你的问题是你的基类python包装器(LinkPredictor)需要包含一个指针成员,然后可以被派生类覆盖。
举个例子说我们正在包装以下c ++库:
foo.hpp
class Base { public: virtual double a(); }; class Derived : public Base { public: virtual double a(); }; class Using { public: double a; Using(Base *b); };Foo.cpp中
#include "foo.hpp" double Base::a() { return 1.0; } double Derived::a() { return 2.0; } Using::Using(Base *b) : a(b->a()) {}然后我们可以将包装器写为
pyfoo.pyx
cdef extern from "foo.hpp": cdef cppclass Base: Base() except + cdef cppclass Derived(Base): Derived() except + cdef cppclass Using: Using(Base *b) except + double a cdef class PyBase(object): cdef Base *_this def __cinit__(self): if type(self) != PyBase: return self._this = new Base() def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULL cdef class PyDerived(PyBase): def __cinit__(self): self._this = new Derived() def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULL cdef class PyUsing(object): cdef Using *_this def __cinit__(self, PyBase b): self._this = new Using(b._this) def a(self): return self._this.a def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULL除此之外,您可能还想阅读本教程
Your problem is that your python wrapper for the base class (LinkPredictor) will need to contain a pointer member which can then be overwritten by the derived classes.
As an example say we are wrapping the following c++ library:
foo.hpp
class Base { public: virtual double a(); }; class Derived : public Base { public: virtual double a(); }; class Using { public: double a; Using(Base *b); };foo.cpp
#include "foo.hpp" double Base::a() { return 1.0; } double Derived::a() { return 2.0; } Using::Using(Base *b) : a(b->a()) {}We could then write the wrapper as
pyfoo.pyx
cdef extern from "foo.hpp": cdef cppclass Base: Base() except + cdef cppclass Derived(Base): Derived() except + cdef cppclass Using: Using(Base *b) except + double a cdef class PyBase(object): cdef Base *_this def __cinit__(self): if type(self) != PyBase: return self._this = new Base() def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULL cdef class PyDerived(PyBase): def __cinit__(self): self._this = new Derived() def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULL cdef class PyUsing(object): cdef Using *_this def __cinit__(self, PyBase b): self._this = new Using(b._this) def a(self): return self._this.a def __dealloc__(self): if self._this is not NULL: del self._this self._this = NULLIn addition to this you might want to read through this tutorial
更多推荐
发布评论