在Python中使用Boost.python覆盖C ++虚拟函数?

问题描述

我有一个带有虚方法的C ++类:

// C ++ A级 {

public:
    A() {};
    virtual int override_me(int a) {return 2*a;};
    int calculate(int a) { return this->override_me(a) ;}

};

我想做的是使用Boost.python将此类公开给Python,从Python中的此类继承,并具有正确的覆盖名称

#python:
class B(A):
   def override_me(self,a):
       return 5*a
b = B()
b.calculate(1) # should return 5 instead of 2

我想对纯虚函数做同样的事情。我正在寻找一种不在类A上用C ++创建任何包装类的方法。这有可能吗?如果是/否,我该怎么办?

解决方法

您可以在类周围提供一个精简包装,将override_me方法调用委托给特定于boost::python的重写函数。

派生类calculate的调用只需调用父类calculate的方法,因此从Python调用它们时,它们将调用C ++定义的calculate方法,但仍允许{{1} }方法要从Python覆盖:

override_me

g ++ virtual_override.cpp -fPIC -shared -I / path / to / include / python3 -L / path / to / libpython3 -o my_lib.so -lpython3 -lboost_python3

示例:

这允许非纯粹的情况,例如,当不重写override_me时,默认函数称为:

#include <boost/python.hpp>
using namespace boost;
using namespace boost::python;

class A {

public:
    A() {};
    virtual int override_me(int a) {
        return 2*a;
    };
    virtual int calculate(int a) {
        return this->override_me(a);
    }
};

struct AWrap: A,public boost::python::wrapper<A> {
    AWrap() : A() {};
    int override_me(int a) override {
        if (override f = this->get_override("override_me")) {
            return this->get_override("override_me")(a);
        } else {
            return A::override_me(a);
        }
    };
    int calculate(int a) override {
        return A::calculate(a);
    }
};

BOOST_PYTHON_MODULE(my_lib)
{
      python::class_<AWrap,boost::noncopyable>("A",python::init<>())
      .def("override_me",&AWrap::override_me)
      .def("calculate",&AWrap::calculate);
}

int main() {}

2

但是可以从Python中进行虚拟覆盖:

import my_lib

class B(my_lib.A):
    pass
b = B()

print (b.calculate(1))

5

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...