[C++-sig] Interface design.
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Tue Apr 22 20:20:25 CEST 2003
Hi!
This is a very nice overview of component based development with Boost.Python!
I'd like to add one more great discovery (thanks to Dave):
It is easily possible to add member functions/methods from Python.
For example:
In C++:
class_<point>("point") ... ;
Now in Python, e.g. in Bruno's __init__.py file:
# a regular function
def point_repr(self):
return str((self.x, self.y))
# now we turn it into a member function
point.__repr__ = point_repr
*All* point instances created from C++ will have this pure-Python
member function!
We use this trick to:
- keep all I/O related code out of our C++ libraries (no trouble with
redirecting)
- cut down compile times to zero for these additional functions
- reduce the memory footprint to virtually zero
- minimize the need to recompile
- rapid prototyping (you can move the code to C++ if required without
changing the interface)
- have less source code
Another useful idea is to replace constructors with factory functions:
_point = point
def point(x=0, y=0):
return _point(x, y)
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.
Ralf
--- Nicodemus <nicodemus at globalite.com.br> wrote:
> Hi!
>
> Suppose you want to have a top level package in python named kikura,
> with two sub-modules, core and node, so that a user uses your package
> like this:
>
> import kikura.core
> import kikura.node
> kikura.core.Foo()
>
>
> You can acomplish this generating the two sub-modules (core and node)
> using Boost.Python, like any other module:
>
> // file core.cpp
> BOOST_PYTHON_MODULE(core)
> {
> ...
> }
>
> // file node.cpp
> BOOST_PYTHON_MODULE(node)
> {
> ...
> }
>
> And creating the following directory structure:
>
> /kikura
> __init__.py
> core.pyd
> node.pyd
>
>
> And that's it (the file __init__.py indicates that the directory is a
> package. It can be empty, but it can be useful to provide a more
> friendly interface for your users. See below).
>
> I suggest that you name your bindings _core and _node, thought, and make
> the sub-modules *python* modules which import the funcionality of the
> bindings, like so:
>
> /kikura
> __init__.py
> /core
> __init__.py
> _core.pyd
> /node
> __init__.py
> _node.pyd
>
>
> with /kikura/core/__init__.py contains the statement "from _core import
> *". The same for the node package. Why do it like this? Well, because
> then you can easily implement some things in python in a way that is
> transparent for the user (I am assuming here that you're developing this
> library). Suppose you want to add a new utility function into the core
> package, made in python. You just create a file "foo.py" and put it
> inside /kikura/core, and add this line to its __init__.py:
>
> from foo import util_function, other_function
>
>
> and your users will access it like so:
>
> import kikura.core
> kikura.core.util_function(10)
>
>
> Back to the compilation time issue, notice that you don't have to write
> all class_ declarations inside the BOOST_PYTHON_MODULE macro directly,
> you can split them in any number of files you like. For example:
>
> // file Foo.cpp
> #include <kikura/Foo.h>
> void export_foo()
> {
> class_<Foo>()...
> }
>
> // file Bar.cpp
> #include <kikura/Bar.h>
> void export_bar()
> {
> class_<Bar>()...
> }
>
> // file core.cpp
> void export_foo();
> void export_bar();
> BOOST_PYTHON_MODULE(core)
> {
> export_foo();
> export_bar();
> }
>
>
> This will take longer to compile than a single file (because the
> Boost.Python headers must be compiled for each cpp), but if your
> developing the library this is a big help, because a change in a header
> doesn't mean the entire bindings will have to be recompiled.
>
> Hope that helps,
> Nicodemus.
__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com
More information about the Cplusplus-sig
mailing list