Now let's expose a C++ class to Python:
#include <iostream> #include <string> namespace { // Avoid cluttering the global namespace. // A friendly class. class hello { public: hello(const std::string& country) { this->country = country; } std::string greet() const { return "Hello from " + country; } private: std::string country; }; // A function taking a hello object as an argument. std::string invite(const hello& w) { return w.greet() + "! Please come soon!"; } }
To expose the class, we use a class_builder in addition to the module_builder from the previous example. Class member functions are exposed by using the def() member function on the class_builder:
#include <boost/python/class_builder.hpp> namespace python = boost::python; BOOST_PYTHON_MODULE_INIT(getting_started2) { try { // Create an object representing this extension module. python::module_builder this_module("getting_started2"); // Create the Python type object for our extension class. python::class_builder<hello> hello_class(this_module, "hello"); // Add the __init__ function. hello_class.def(python::constructor<std::string>()); // Add a regular member function. hello_class.def(&hello::greet, "greet"); // Add invite() as a regular function to the module. this_module.def(invite, "invite"); // Even better, invite() can also be made a member of hello_class!!! hello_class.def(invite, "invite"); } catch(...) { python::handle_exception(); // Deal with the exception for Python } }
Now we can use the class normally from Python:
Notes:>>> from getting_started2 import * >>> hi = hello('California') >>> hi.greet() 'Hello from California' >>> invite(hi) 'Hello from California! Please come soon!' >>> hi.invite() 'Hello from California! Please come soon!'
We can even make a subclass of hello.world
:
>>> class wordy(hello): ... def greet(self): ... return hello.greet(self) + ', where the weather is fine' ... >>> hi2 = wordy('Florida') >>> hi2.greet() 'Hello from Florida, where the weather is fine' >>> invite(hi2) 'Hello from Florida! Please come soon!'
Pretty cool! You can't do that with an ordinary Python extension type! Of course, you may now have a slightly empty feeling in the pit of your little pythonic stomach. Perhaps you wanted to see the following wordy invitation:
After all, invite calls hello::greet(), and you reimplemented that in your Python subclass, wordy. If so, read on...'Hello from Florida, where the weather is fine! Please come soon!'
Next: Overridable virtual functions Previous: A Simple Example Up: Top
© Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.
Updated: Mar 6, 2001