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

boost.python/Inheritance (last edited 2008-11-15 14:00:35 by localhost)

Unable to edit the page? See the FrontPage for instructions.