Inheritance in Python
Boost.Python extension classes support single and multiple-inheritance in Python, just like regular Python classes. You can arbitrarily mix built-in Python classes with extension classes in a derived class' tuple of bases. Whenever a Boost.Python extension class is among the bases for a new class in Python, the result is an extension class:
>>> class MyPythonClass: ... def f(): return 'MyPythonClass.f()' ... >>> import my_extension_module >>> class Derived(my_extension_module.MyExtensionClass, MyPythonClass): ... '''This is an extension class''' ... pass ... >>> x = Derived() >>> x.f() 'MyPythonClass.f()' >>> x.g() 'MyExtensionClass.g()'
Reflecting C++ Inheritance Relationships
Boost.Python also allows us to represent C++ inheritance relationships so that wrapped derived classes may be passed where values, pointers, or references to a base class are expected as arguments. The declare_base member function of class_builder<> is used to establish the relationship between base and derived classes:
#include <memory> // for std::auto_ptr<>
struct Base {
virtual ~Base() {}
virtual const char* name() const { return "Base"; }
};
struct Derived : Base {
Derived() : x(-1) {}
virtual const char* name() const { return "Derived"; }
int x;
};
std::auto_ptr<Base> derived_as_base() {
return std::auto_ptr<Base>(new Derived);
}
const char* get_name(const Base& b) {
return b.name();
}
int get_derived_x(const Derived& d) {
return d.x;
}
--------------------------------------------------------------------------------
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(my_module)
{
class_<Base>("Base", no_init);
class_<Derived, bases<Base> >("Derived", no_init);
def("derived_as_base", derived_as_base);
def("get_name", get_name);
def("get_derived_x", get_derived_x);
}Then, in Python:
>>> from my_module import * >>> base = Base() >>> derived = Derived() >>> get_name(base) 'Base'
objects of wrapped class Derived may be passed where Base is expected
>>> get_name(derived) 'Derived'
objects of wrapped class Derived can be passed where Derived is expected but where type information has been lost.
>>> get_derived_x(derived_as_base()) -1
