Boost::Python: inheritance + optional parameters
Dear list, This is my first post here, so I'll briefly introduce myself. My name is Sybren and I'm a PhD student at the Utrecht University. We use Boost a lot in our C++-based framework, and naturally we use Boost::Python to create our Python bindings. I want to combine two "features" that are documented well separately, however so far I haven't been able to combine them. What I want to do is have a class in C++ with virtual methods and override them in a Python subclass, AND have those virtual methods use parameters with default values. In short, I want to wrap a class like this: class ExampleClass { public: virtual std::string override_me(int x, int y=0, bool z=false) { std::stringstream msg; msg << "(x=" << x << ", y=" << y << ", z=" << z << ", base implementation"; return msg.str(); } }; And be able to produce a subclass in Python like this: from cpp_module import ExampleClass class Subclass(ExampleClass): def override_me(self, *args): return ExampleClass.override_me(self, *args) + " has been overridden" Of course all in such a way that when I pass a Subclass instance to an ExampleClass parameter of C++ code, and that C++ code calls instance.override_me(1, 2), it returns "x=1, y=2, z=false, base implementation has been overridden". I can't seem to find any documentation about this, and what I find on this mailing list was posted several years ago and involves manually creating as many methods as there are optional parameters. I hope that in recent versions of Boost (I'm using 1.48 but have no problem upgrading to the latest release) there is a more useful technique. With kind regards, -- Sybren A. Stüvel http://stuvel.eu/
On 04/27/2012 10:38 AM, Sybren A. Stüvel wrote:
Dear list,
This is my first post here, so I'll briefly introduce myself. My name is Sybren and I'm a PhD student at the Utrecht University. We use Boost a lot in our C++-based framework, and naturally we use Boost::Python to create our Python bindings. I want to combine two "features" that are documented well separately, however so far I haven't been able to combine them. What I want to do is have a class in C++ with virtual methods and override them in a Python subclass, AND have those virtual methods use parameters with default values. In short, I want to wrap a class like this:
class ExampleClass { public: virtual std::string override_me(int x, int y=0, bool z=false) { std::stringstream msg; msg<< "(x="<< x<< ", y="<< y<< ", z="<< z<< ", base implementation"; return msg.str(); } };
And be able to produce a subclass in Python like this:
from cpp_module import ExampleClass class Subclass(ExampleClass): def override_me(self, *args): return ExampleClass.override_me(self, *args) + " has been overridden"
Of course all in such a way that when I pass a Subclass instance to an ExampleClass parameter of C++ code, and that C++ code calls instance.override_me(1, 2), it returns "x=1, y=2, z=false, base implementation has been overridden".
I can't seem to find any documentation about this, and what I find on this mailing list was posted several years ago and involves manually creating as many methods as there are optional parameters. I hope that in recent versions of Boost (I'm using 1.48 but have no problem upgrading to the latest release) there is a more useful technique.
Have you tried using the keyword argument approach to handling default arguments? More precisely, something like this should work, I think: def("override", func, (arg("x"), arg("y")=0, arg("z")=false)) (where func is the usual wrapper override function). The disadvantage is that you have to repeat the default arguments in the wrapper code, but the advantage is that from Python you can use keyword arguments in their full glory and you don't have to worry about wrapping multiple C++ overloads. Jim
On 27 April 2012 17:17, Jim Bosch <talljimbo@gmail.com> wrote:
Have you tried using the keyword argument approach to handling default arguments? More precisely, something like this should work, I think:
def("override", func, (arg("x"), arg("y")=0, arg("z")=false))
(where func is the usual wrapper override function).
It does, nearly, and I tweaked it to: def("override", WrapperClass::func, WrapperClass::default_func, (arg("x"), arg("y")=0, arg("z")=false)) Thank you for your quick answer, you have helped me a lot. Kind regards, -- Sybren A. Stüvel http://stuvel.eu/
Hello, I using bjam to compile my C++ program with Boost.Python But I have a link error : error LNK2019: unresolved external symbol "__declspec(dllimport).... so I try to add my library in the Jamroot file : project : requirements <library>/boost/python//boost_python <library-path>D:/localExt_win32_cl10-0Exp/lib <library-path>D:/local/bin <include> ..... It that right ? thanks
participants (3)
-
Jim Bosch -
Sybren A. Stüvel -
Yoann Chaumy