Boost Python - class_<T> As object
Hi all, I've not posted to this discussion list before, but I have been subscribed and following it loosely for a year now. I was looking through the boost python docs and found something interesting: class_<T> as objects Due to the dynamic nature of Boost.Python objects, any class_<T> may also be one of these types! The following code snippet wraps the class (type) object. We can use this to create wrapped instances. Example: object vec345 = ( class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle) )(3.0, 4.0); assert(vec345.attr("length") == 5.0); This is nice, but I'm wondering about the inline class_<> declaration. Specifically I don't want to copy and paste the entire class_<> stuff everytime I want to create a python object of a exported c++ class and use it in c++. This violates the rule of duplication as a bad thing. How could I avoid this? Looking at it as I write, I think it may be possible to save the entire thing as a C++ variable and then use it elsewhere. class_<Vec2> g_Vec2 = class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle); And then I use it like so ?: object vec345 = g_Vec2(3.0,4.0); object vec_other = g_Vec2(7.0,7.0); And use it inside the module declaration as well: BOOST_PYTHON_MODULE(mymodule) ( g_Vec2; ... ) I may be totally off here, but hopefully I've given a clear picture of what I'm trying to do. I just want to put everything in one place if I can. Thanks for reading! -Dan
Dan Eloff wrote:
This is nice, but I'm wondering about the inline class_<> declaration. Specifically I don't want to copy and paste the entire class_<> stuff everytime I want to create a python object of a exported c++ class and use it in c++. This violates the rule of duplication as a bad thing. How could I avoid this? Looking at it as I write, I think it may be possible to save the entire thing as a C++ variable and then use it elsewhere.
class_<Vec2> g_Vec2 = class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle);
And then I use it like so ?:
object vec345 = g_Vec2(3.0,4.0); object vec_other = g_Vec2(7.0,7.0);
And use it inside the module declaration as well:
BOOST_PYTHON_MODULE(mymodule) ( g_Vec2; ... )
I may be totally off here, but hopefully I've given a clear picture of what I'm trying to do. I just want to put everything in one place if I can.
I think you got it right. 'g_Vec2' represents a (python) type, and 'g_Vec2(...)' invokes __call__ on it, which is a constructor call in this case, i.e. a factory that returns an instance of type 'g_Vec2'. Regards, Stefan
Dan Eloff <dan.eloff@gmail.com> writes:
Hi all, I've not posted to this discussion list before, but I have been subscribed and following it loosely for a year now.
I was looking through the boost python docs and found something interesting:
class_<T> as objects
Due to the dynamic nature of Boost.Python objects, any class_<T> may also be one of these types! The following code snippet wraps the class (type) object.
We can use this to create wrapped instances. Example:
object vec345 = ( class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle) )(3.0, 4.0);
assert(vec345.attr("length") == 5.0);
This is nice, but I'm wondering about the inline class_<> declaration. Specifically I don't want to copy and paste the entire class_<> stuff everytime I want to create a python object of a exported c++ class and use it in c++. This violates the rule of duplication as a bad thing. How could I avoid this? Looking at it as I write, I think it may be possible to save the entire thing as a C++ variable and then use it elsewhere.
class_<Vec2> g_Vec2 = class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle);
Well, I'm not sure that class_<T> has a copy ctor. But as you've been saying, why repeat yourself? object g_Vec2 = class_<Vec2>("Vec2", init<double, double>()) .def_readonly("length", &Point::length) .def_readonly("angle", &Point::angle) ; object vec345 = g_Vec2(3.0,4.0); object vec_other = g_Vec2(7.0,7.0); If the tutorial doesn't make it crystal clear that you can do that, it should. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
Dan Eloff -
David Abrahams -
Stefan Seefeld