mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
144 lines
4.6 KiB
HTML
144 lines
4.6 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
|
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
|
<title>
|
|
Exporting Classes
|
|
</title>
|
|
<div>
|
|
<h1>
|
|
<img width="277" height="86" id="_x0000_i1025" src="../../../c++boost.gif" alt=
|
|
"c++boost.gif (8819 bytes)">
|
|
</h1>
|
|
<h1>
|
|
Exporting Classes
|
|
</h1>
|
|
<p>
|
|
Now let's expose a C++ class to Python:
|
|
|
|
<blockquote><pre>
|
|
#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!";
|
|
}
|
|
}
|
|
|
|
</blockquote></pre> <p>
|
|
To expose the class, we use a <tt>class_builder</tt> in addition to the
|
|
<tt>module_builder</tt> from the previous example. Class member functions
|
|
are exposed by using the <tt>def()</tt> member function on the
|
|
<tt>class_builder</tt>:
|
|
<blockquote><pre>
|
|
#include <boost/python/class_builder.hpp>
|
|
namespace python = boost::python;
|
|
|
|
BOOST_PYTHON_MODULE_INIT(getting_started2)
|
|
{
|
|
// 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");
|
|
}
|
|
</blockquote></pre>
|
|
<p>
|
|
Now we can use the class normally from Python:
|
|
|
|
<blockquote><pre>
|
|
>>> 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!'
|
|
</blockquote></pre>
|
|
|
|
Notes:<ul>
|
|
<li> We expose the class' constructor by calling <tt>def()</tt> on the
|
|
<tt>class_builder</tt> with an argument whose type is
|
|
<tt>constructor<</tt><i>params</i><tt>></tt>, where <i>params</i>
|
|
matches the list of constructor argument types:
|
|
|
|
|
|
<li>Regular member functions are defined by calling <tt>def()</tt> with a
|
|
member function pointer and its Python name:
|
|
|
|
<li>Any function added to a class whose initial argument matches the class (or
|
|
any base) will act like a member function in Python.
|
|
|
|
<li>To define a nested class, just pass the enclosing
|
|
<tt>class_builder</tt> (instead of a <tt>module_builder</tt>) as the
|
|
first argument to the nested <tt>class_builder</tt>'s constructor.
|
|
|
|
|
|
</ul>
|
|
<p>
|
|
We can even make a subclass of <code>hello.world</code>:
|
|
|
|
<blockquote><pre>
|
|
>>> 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!'
|
|
</blockquote></pre>
|
|
<p>
|
|
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
|
|
<tt>wordy</tt> invitation:
|
|
|
|
<blockquote><pre>
|
|
'Hello from Florida, where the weather is fine! Please come soon!'
|
|
</blockquote></pre>
|
|
|
|
After all, <tt>invite</tt> calls <tt>hello::greet()</tt>, and you
|
|
reimplemented that in your Python subclass, <tt>wordy</tt>. If so, <a
|
|
href= "overriding.html">read on</a>...
|
|
|
|
<p>
|
|
Next: <a href="overriding.html">Overridable virtual functions</a>
|
|
Previous: <a href="example1.html">A Simple Example</a> Up:
|
|
<a href="index.html">Top</a>
|
|
<p>
|
|
© 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.
|
|
<p>
|
|
Updated: Mar 6, 2001
|
|
</div>
|
|
|