]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [article Boost.Python Tutorial |
2 | [quickbook 1.6] | |
3 | [authors [de Guzman, Joel], [Abrahams, David]] | |
4 | [copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams] | |
5 | [category inter-language support] | |
6 | [id tutorial] | |
7 | [purpose | |
8 | Reflects C++ classes and functions into Python | |
9 | ] | |
10 | [license | |
11 | Distributed under the Boost Software License, Version 1.0. | |
12 | (See accompanying file LICENSE_1_0.txt or copy at | |
13 | [@http://www.boost.org/LICENSE_1_0.txt] | |
14 | ] | |
15 | ] | |
16 | ||
17 | [/ QuickBook Document version 0.9 ] | |
18 | ||
19 | [def __note__ [$../images/note.png]] | |
20 | [def __alert__ [$../images/alert.png]] | |
21 | [def __tip__ [$../images/tip.png]] | |
22 | [def :-) [$../images/smiley.png]] | |
23 | [def __jam__ [$../images/jam.png]] | |
24 | ||
25 | [section QuickStart] | |
26 | ||
27 | The Boost Python Library is a framework for interfacing Python and | |
28 | C++. It allows you to quickly and seamlessly expose C++ classes | |
29 | functions and objects to Python, and vice-versa, using no special | |
30 | tools -- just your C++ compiler. It is designed to wrap C++ interfaces | |
31 | non-intrusively, so that you should not have to change the C++ code at | |
32 | all in order to wrap it, making Boost.Python ideal for exposing | |
33 | 3rd-party libraries to Python. The library's use of advanced | |
34 | metaprogramming techniques simplifies its syntax for users, so that | |
35 | wrapping code takes on the look of a kind of declarative interface | |
36 | definition language (IDL). | |
37 | ||
38 | [h2 Hello World] | |
39 | ||
40 | Following C/C++ tradition, let's start with the "hello, world". A C++ | |
41 | Function: | |
42 | ||
43 | char const* greet() | |
44 | { | |
45 | return "hello, world"; | |
46 | } | |
47 | ||
48 | can be exposed to Python by writing a Boost.Python wrapper: | |
49 | ||
50 | #include <boost/python.hpp> | |
51 | ||
52 | BOOST_PYTHON_MODULE(hello_ext) | |
53 | { | |
54 | using namespace boost::python; | |
55 | def("greet", greet); | |
56 | } | |
57 | ||
58 | That's it. We're done. We can now build this as a shared library. The | |
59 | resulting DLL is now visible to Python. Here's a sample Python session: | |
60 | ||
61 | [python] | |
62 | ||
63 | >>> import hello_ext | |
64 | >>> print hello_ext.greet() | |
65 | hello, world | |
66 | ||
67 | [c++] | |
68 | ||
69 | [:['[*Next stop... Building your Hello World module from start to finish...]]] | |
70 | ||
71 | [endsect] | |
72 | [section:hello Building Hello World] | |
73 | ||
74 | [h2 From Start To Finish] | |
75 | ||
76 | Now the first thing you'd want to do is to build the Hello World module and | |
77 | try it for yourself in Python. In this section, we will outline the steps | |
78 | necessary to achieve that. We will use the build tool that comes bundled | |
79 | with every boost distribution: [*bjam]. | |
80 | ||
81 | [note [*Building without bjam] | |
82 | ||
83 | Besides bjam, there are of course other ways to get your module built. | |
84 | What's written here should not be taken as "the one and only way". | |
85 | There are of course other build tools apart from [^bjam]. | |
86 | ||
87 | Take note however that the preferred build tool for Boost.Python is bjam. | |
88 | There are so many ways to set up the build incorrectly. Experience shows | |
89 | that 90% of the "I can't build Boost.Python" problems come from people | |
90 | who had to use a different tool. | |
91 | ] | |
92 | ||
93 | We will skip over the details. Our objective will be to simply create | |
94 | the hello world module and run it in Python. For a complete reference to | |
95 | building Boost.Python, check out: [@../../../building.html | |
96 | building.html]. After this brief ['bjam] tutorial, we should have built | |
97 | the DLLs and run a python program using the extension. | |
98 | ||
99 | The tutorial example can be found in the directory: | |
100 | [^libs/python/example/tutorial]. There, you can find: | |
101 | ||
102 | * hello.cpp | |
103 | * hello.py | |
104 | * Jamroot | |
105 | ||
106 | The [^hello.cpp] file is our C++ hello world example. The [^Jamroot] is | |
107 | a minimalist ['bjam] script that builds the DLLs for us. Finally, | |
108 | [^hello.py] is our Python program that uses the extension in | |
109 | [^hello.cpp]. | |
110 | ||
111 | Before anything else, you should have the bjam executable in your boost | |
112 | directory or somewhere in your path such that [^bjam] can be executed in | |
113 | the command line. Pre-built Boost.Jam executables are available for most | |
114 | platforms. The complete list of Bjam executables can be found | |
115 | [@http://sourceforge.net/project/showfiles.php?group_id=7586 here]. | |
116 | ||
117 | [h2 Let's Jam!] | |
118 | __jam__ | |
119 | ||
120 | [@../../../../example/tutorial/Jamroot Here] is our minimalist Jamroot | |
121 | file. Simply copy the file and tweak [^use-project boost] to where your | |
122 | boost root directory is and you're OK. | |
123 | ||
124 | The comments contained in the Jamrules file above should be sufficient | |
125 | to get you going. | |
126 | ||
127 | [h2 Running bjam] | |
128 | ||
129 | ['bjam] is run using your operating system's command line interpreter. | |
130 | ||
131 | [:Start it up.] | |
132 | ||
133 | A file called user-config.jam in your home directory is used to | |
134 | configure your tools. In Windows, your home directory can be found by | |
135 | typing: | |
136 | ||
137 | [pre | |
138 | ECHO %HOMEDRIVE%%HOMEPATH% | |
139 | ] | |
140 | ||
141 | into a command prompt window. Your file should at least have the rules | |
142 | for your compiler and your python installation. A specific example of | |
143 | this on Windows would be: | |
144 | ||
145 | [pre | |
146 | # MSVC configuration | |
147 | using msvc : 8.0 ; | |
148 | ||
149 | # Python configuration | |
150 | using python : 2.4 : C:/dev/tools/Python/ ; | |
151 | ] | |
152 | ||
153 | The first rule tells Bjam to use the MSVC 8.0 compiler and associated | |
154 | tools. The second rule provides information on Python, its version and | |
155 | where it is located. The above assumes that the Python installation is | |
156 | in [^C:/dev/tools\/Python/]. If you have one fairly "standard" python | |
157 | installation for your platform, you might not need to do this. | |
158 | ||
159 | Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial] | |
160 | where the tutorial [^"hello.cpp"] and the [^"Jamroot"] is situated. | |
161 | ||
162 | Finally: | |
163 | ||
164 | bjam | |
165 | ||
166 | It should be building now: | |
167 | ||
168 | [pre | |
169 | cd C:\dev\boost\libs\python\example\tutorial | |
170 | bjam | |
171 | ...patience... | |
172 | ...found 1101 targets... | |
173 | ...updating 35 targets... | |
174 | ] | |
175 | ||
176 | And so on... Finally: | |
177 | ||
178 | [pre | |
179 | Creating library /path-to-boost_python.dll/ | |
180 | Creating library /path-to-'''hello_ext'''.exp/ | |
181 | '''**passed**''' ... hello.test | |
182 | ...updated 35 targets... | |
183 | ] | |
184 | ||
185 | Or something similar. If all is well, you should now have built the DLLs and | |
186 | run the Python program. | |
187 | ||
188 | [:[*There you go... Have fun!]] | |
189 | ||
190 | [endsect] | |
191 | [section:exposing Exposing Classes] | |
192 | ||
193 | Now let's expose a C++ class to Python. | |
194 | ||
195 | Consider a C++ class/struct that we want to expose to Python: | |
196 | ||
197 | struct World | |
198 | { | |
199 | void set(std::string msg) { this->msg = msg; } | |
200 | std::string greet() { return msg; } | |
201 | std::string msg; | |
202 | }; | |
203 | ||
204 | We can expose this to Python by writing a corresponding Boost.Python | |
205 | C++ Wrapper: | |
206 | ||
207 | #include <boost/python.hpp> | |
208 | using namespace boost::python; | |
209 | ||
210 | BOOST_PYTHON_MODULE(hello) | |
211 | { | |
212 | class_<World>("World") | |
213 | .def("greet", &World::greet) | |
214 | .def("set", &World::set) | |
215 | ; | |
216 | } | |
217 | ||
218 | Here, we wrote a C++ class wrapper that exposes the member functions | |
219 | [^greet] and [^set]. Now, after building our module as a shared library, we | |
220 | may use our class [^World] in Python. Here's a sample Python session: | |
221 | ||
222 | [python] | |
223 | ||
224 | >>> import hello | |
225 | >>> planet = hello.World() | |
226 | >>> planet.set('howdy') | |
227 | >>> planet.greet() | |
228 | 'howdy' | |
229 | ||
230 | [section Constructors] | |
231 | ||
232 | Our previous example didn't have any explicit constructors. | |
233 | Since [^World] is declared as a plain struct, it has an implicit default | |
234 | constructor. Boost.Python exposes the default constructor by default, | |
235 | which is why we were able to write | |
236 | ||
237 | >>> planet = hello.World() | |
238 | ||
239 | We may wish to wrap a class with a non-default constructor. Let us | |
240 | build on our previous example: | |
241 | ||
242 | [c++] | |
243 | ||
244 | struct World | |
245 | { | |
246 | World(std::string msg): msg(msg) {} // added constructor | |
247 | void set(std::string msg) { this->msg = msg; } | |
248 | std::string greet() { return msg; } | |
249 | std::string msg; | |
250 | }; | |
251 | ||
252 | This time [^World] has no default constructor; our previous | |
253 | wrapping code would fail to compile when the library tried to expose | |
254 | it. We have to tell [^class_<World>] about the constructor we want to | |
255 | expose instead. | |
256 | ||
257 | #include <boost/python.hpp> | |
258 | using namespace boost::python; | |
259 | ||
260 | BOOST_PYTHON_MODULE(hello) | |
261 | { | |
262 | class_<World>("World", init<std::string>()) | |
263 | .def("greet", &World::greet) | |
264 | .def("set", &World::set) | |
265 | ; | |
266 | } | |
267 | ||
268 | [^init<std::string>()] exposes the constructor taking in a | |
269 | [^std::string] (in Python, constructors are spelled | |
270 | "[^"__init__"]"). | |
271 | ||
272 | We can expose additional constructors by passing more [^init<...>]s to | |
273 | the [^def()] member function. Say for example we have another World | |
274 | constructor taking in two doubles: | |
275 | ||
276 | class_<World>("World", init<std::string>()) | |
277 | .def(init<double, double>()) | |
278 | .def("greet", &World::greet) | |
279 | .def("set", &World::set) | |
280 | ; | |
281 | ||
282 | On the other hand, if we do not wish to expose any constructors at | |
283 | all, we may use [^no_init] instead: | |
284 | ||
285 | class_<Abstract>("Abstract", no_init) | |
286 | ||
287 | This actually adds an [^__init__] method which always raises a | |
288 | Python RuntimeError exception. | |
289 | ||
290 | [endsect] | |
291 | [section Class Data Members] | |
292 | ||
293 | Data members may also be exposed to Python so that they can be | |
294 | accessed as attributes of the corresponding Python class. Each data | |
295 | member that we wish to be exposed may be regarded as [*read-only] or | |
296 | [*read-write]. Consider this class [^Var]: | |
297 | ||
298 | struct Var | |
299 | { | |
300 | Var(std::string name) : name(name), value() {} | |
301 | std::string const name; | |
302 | float value; | |
303 | }; | |
304 | ||
305 | Our C++ [^Var] class and its data members can be exposed to Python: | |
306 | ||
307 | class_<Var>("Var", init<std::string>()) | |
308 | .def_readonly("name", &Var::name) | |
309 | .def_readwrite("value", &Var::value); | |
310 | ||
311 | Then, in Python, assuming we have placed our Var class inside the namespace | |
312 | hello as we did before: | |
313 | ||
314 | [python] | |
315 | ||
316 | >>> x = hello.Var('pi') | |
317 | >>> x.value = 3.14 | |
318 | >>> print x.name, 'is around', x.value | |
319 | pi is around 3.14 | |
320 | ||
321 | Note that [^name] is exposed as [*read-only] while [^value] is exposed | |
322 | as [*read-write]. | |
323 | ||
324 | >>> x.name = 'e' # can't change name | |
325 | Traceback (most recent call last): | |
326 | File "<stdin>", line 1, in ? | |
327 | AttributeError: can't set attribute | |
328 | ||
329 | [endsect] | |
330 | [section Class Properties] | |
331 | ||
332 | In C++, classes with public data members are usually frowned | |
333 | upon. Well designed classes that take advantage of encapsulation hide | |
334 | the class' data members. The only way to access the class' data is | |
335 | through access (getter/setter) functions. Access functions expose class | |
336 | properties. Here's an example: | |
337 | ||
338 | [c++] | |
339 | ||
340 | struct Num | |
341 | { | |
342 | Num(); | |
343 | float get() const; | |
344 | void set(float value); | |
345 | ... | |
346 | }; | |
347 | ||
348 | However, in Python attribute access is fine; it doesn't neccessarily break | |
349 | encapsulation to let users handle attributes directly, because the | |
350 | attributes can just be a different syntax for a method call. Wrapping our | |
351 | [^Num] class using Boost.Python: | |
352 | ||
353 | class_<Num>("Num") | |
354 | .add_property("rovalue", &Num::get) | |
355 | .add_property("value", &Num::get, &Num::set); | |
356 | ||
357 | And at last, in Python: | |
358 | ||
359 | [python] | |
360 | ||
361 | >>> x = Num() | |
362 | >>> x.value = 3.14 | |
363 | >>> x.value, x.rovalue | |
364 | (3.14, 3.14) | |
365 | >>> x.rovalue = 2.17 # error! | |
366 | ||
367 | Take note that the class property [^rovalue] is exposed as [*read-only] | |
368 | since the [^rovalue] setter member function is not passed in: | |
369 | ||
370 | [c++] | |
371 | ||
372 | .add_property("rovalue", &Num::get) | |
373 | ||
374 | [endsect] | |
375 | [section Inheritance] | |
376 | ||
377 | In the previous examples, we dealt with classes that are not polymorphic. | |
378 | This is not often the case. Much of the time, we will be wrapping | |
379 | polymorphic classes and class hierarchies related by inheritance. We will | |
380 | often have to write Boost.Python wrappers for classes that are derived from | |
381 | abstract base classes. | |
382 | ||
383 | Consider this trivial inheritance structure: | |
384 | ||
385 | struct Base { virtual ~Base(); }; | |
386 | struct Derived : Base {}; | |
387 | ||
388 | And a set of C++ functions operating on [^Base] and [^Derived] object | |
389 | instances: | |
390 | ||
391 | void b(Base*); | |
392 | void d(Derived*); | |
393 | Base* factory() { return new Derived; } | |
394 | ||
395 | We've seen how we can wrap the base class [^Base]: | |
396 | ||
397 | class_<Base>("Base") | |
398 | /*...*/ | |
399 | ; | |
400 | ||
401 | Now we can inform Boost.Python of the inheritance relationship between | |
402 | [^Derived] and its base class [^Base]. Thus: | |
403 | ||
404 | class_<Derived, bases<Base> >("Derived") | |
405 | /*...*/ | |
406 | ; | |
407 | ||
408 | Doing so, we get some things for free: | |
409 | ||
410 | # Derived automatically inherits all of Base's Python methods | |
411 | (wrapped C++ member functions) | |
412 | # [*If] Base is polymorphic, [^Derived] objects which have been passed to | |
413 | Python via a pointer or reference to [^Base] can be passed where a pointer | |
414 | or reference to [^Derived] is expected. | |
415 | ||
416 | Now, we will expose the C++ free functions [^b] and [^d] and [^factory]: | |
417 | ||
418 | def("b", b); | |
419 | def("d", d); | |
420 | def("factory", factory); | |
421 | ||
422 | Note that free function [^factory] is being used to generate new | |
423 | instances of class [^Derived]. In such cases, we use | |
424 | [^return_value_policy<manage_new_object>] to instruct Python to adopt | |
425 | the pointer to [^Base] and hold the instance in a new Python [^Base] | |
426 | object until the the Python object is destroyed. We will see more of | |
427 | Boost.Python [link tutorial.functions.call_policies call policies] later. | |
428 | ||
429 | // Tell Python to take ownership of factory's result | |
430 | def("factory", factory, | |
431 | return_value_policy<manage_new_object>()); | |
432 | ||
433 | [endsect] | |
434 | ||
435 | [section Class Virtual Functions] | |
436 | ||
437 | In this section, we will learn how to make functions behave polymorphically | |
438 | through virtual functions. Continuing our example, let us add a virtual function | |
439 | to our [^Base] class: | |
440 | ||
441 | struct Base | |
442 | { | |
443 | virtual ~Base() {} | |
444 | virtual int f() = 0; | |
445 | }; | |
446 | ||
447 | One of the goals of Boost.Python is to be minimally intrusive on an existing C++ | |
448 | design. In principle, it should be possible to expose the interface for a 3rd | |
449 | party library without changing it. It is not ideal to add anything to our class | |
450 | `Base`. Yet, when you have a virtual function that's going to be overridden in | |
451 | Python and called polymorphically *from C++*, we'll need to add some | |
452 | scaffoldings to make things work properly. What we'll do is write a class | |
453 | wrapper that derives from `Base` that will unintrusively hook into the virtual | |
454 | functions so that a Python override may be called: | |
455 | ||
456 | struct BaseWrap : Base, wrapper<Base> | |
457 | { | |
458 | int f() | |
459 | { | |
460 | return this->get_override("f")(); | |
461 | } | |
462 | }; | |
463 | ||
464 | Notice too that in addition to inheriting from `Base`, we also multiply- | |
465 | inherited `wrapper<Base>` (See [@../reference/high_level_components/boost_python_wrapper_hpp.html#high_level_components.boost_python_wrapper_hpp.class_template_wrapper Wrapper]). The | |
466 | `wrapper` template makes the job of wrapping classes that are meant to | |
467 | overridden in Python, easier. | |
468 | ||
469 | [blurb __alert__ [*MSVC6/7 Workaround] | |
470 | ||
471 | If you are using Microsoft Visual C++ 6 or 7, you have to write `f` as: | |
472 | ||
473 | `return call<int>(this->get_override("f").ptr());`.] | |
474 | ||
475 | BaseWrap's overridden virtual member function `f` in effect calls the | |
476 | corresponding method of the Python object through `get_override`. | |
477 | ||
478 | Finally, exposing `Base`: | |
479 | ||
480 | class_<BaseWrap, boost::noncopyable>("Base") | |
481 | .def("f", pure_virtual(&Base::f)) | |
482 | ; | |
483 | ||
484 | `pure_virtual` signals Boost.Python that the function `f` is a pure virtual | |
485 | function. | |
486 | ||
487 | [note [*member function and methods] | |
488 | ||
489 | Python, like many object oriented languages uses the term [*methods]. | |
490 | Methods correspond roughly to C++'s [*member functions]] | |
491 | ||
492 | [endsect] | |
493 | ||
494 | [section Virtual Functions with Default Implementations] | |
495 | ||
496 | We've seen in the previous section how classes with pure virtual functions are | |
497 | wrapped using Boost.Python's [@../reference/high_level_components/boost_python_wrapper_hpp.html#high_level_components.boost_python_wrapper_hpp.class_template_wrapper class wrapper] | |
498 | facilities. If we wish to wrap [*non]-pure-virtual functions instead, the | |
499 | mechanism is a bit different. | |
500 | ||
501 | Recall that in the [link tutorial.exposing.class_virtual_functions previous section], we | |
502 | wrapped a class with a pure virtual function that we then implemented in C++, or | |
503 | Python classes derived from it. Our base class: | |
504 | ||
505 | struct Base | |
506 | { | |
507 | virtual int f() = 0; | |
508 | }; | |
509 | ||
510 | had a pure virtual function [^f]. If, however, its member function [^f] was | |
511 | not declared as pure virtual: | |
512 | ||
513 | struct Base | |
514 | { | |
515 | virtual ~Base() {} | |
516 | virtual int f() { return 0; } | |
517 | }; | |
518 | ||
519 | We wrap it this way: | |
520 | ||
521 | struct BaseWrap : Base, wrapper<Base> | |
522 | { | |
523 | int f() | |
524 | { | |
525 | if (override f = this->get_override("f")) | |
526 | return f(); // *note* | |
527 | return Base::f(); | |
528 | } | |
529 | ||
530 | int default_f() { return this->Base::f(); } | |
531 | }; | |
532 | ||
533 | Notice how we implemented `BaseWrap::f`. Now, we have to check if there is an | |
534 | override for `f`. If none, then we call `Base::f()`. | |
535 | ||
536 | [blurb __alert__ [*MSVC6/7 Workaround] | |
537 | ||
538 | If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line | |
539 | with the `*note*` as: | |
540 | ||
541 | `return call<char const*>(f.ptr());`.] | |
542 | ||
543 | Finally, exposing: | |
544 | ||
545 | class_<BaseWrap, boost::noncopyable>("Base") | |
546 | .def("f", &Base::f, &BaseWrap::default_f) | |
547 | ; | |
548 | ||
549 | Take note that we expose both `&Base::f` and `&BaseWrap::default_f`. | |
550 | Boost.Python needs to keep track of 1) the dispatch function [^f] and 2) the | |
551 | forwarding function to its default implementation [^default_f]. There's a | |
552 | special [^def] function for this purpose. | |
553 | ||
554 | In Python, the results would be as expected: | |
555 | ||
556 | [python] | |
557 | ||
558 | >>> base = Base() | |
559 | >>> class Derived(Base): | |
560 | ... def f(self): | |
561 | ... return 42 | |
562 | ... | |
563 | >>> derived = Derived() | |
564 | ||
565 | Calling [^base.f()]: | |
566 | ||
567 | >>> base.f() | |
568 | 0 | |
569 | ||
570 | Calling [^derived.f()]: | |
571 | ||
572 | >>> derived.f() | |
573 | 42 | |
574 | ||
575 | [endsect] | |
576 | [section Class Operators/Special Functions] | |
577 | ||
578 | [h2 Python Operators] | |
579 | ||
580 | C is well known for the abundance of operators. C++ extends this to the | |
581 | extremes by allowing operator overloading. Boost.Python takes advantage of | |
582 | this and makes it easy to wrap C++ operator-powered classes. | |
583 | ||
584 | Consider a file position class [^FilePos] and a set of operators that take | |
585 | on FilePos instances: | |
586 | ||
587 | [c++] | |
588 | ||
589 | class FilePos { /*...*/ }; | |
590 | ||
591 | FilePos operator+(FilePos, int); | |
592 | FilePos operator+(int, FilePos); | |
593 | int operator-(FilePos, FilePos); | |
594 | FilePos operator-(FilePos, int); | |
595 | FilePos& operator+=(FilePos&, int); | |
596 | FilePos& operator-=(FilePos&, int); | |
597 | bool operator<(FilePos, FilePos); | |
598 | ||
599 | The class and the various operators can be mapped to Python rather easily | |
600 | and intuitively: | |
601 | ||
602 | class_<FilePos>("FilePos") | |
603 | .def(self + int()) // __add__ | |
604 | .def(int() + self) // __radd__ | |
605 | .def(self - self) // __sub__ | |
606 | .def(self - int()) // __sub__ | |
607 | .def(self += int()) // __iadd__ | |
608 | .def(self -= other<int>()) | |
609 | .def(self < self); // __lt__ | |
610 | ||
611 | The code snippet above is very clear and needs almost no explanation at | |
612 | all. It is virtually the same as the operators' signatures. Just take | |
613 | note that [^self] refers to FilePos object. Also, not every class [^T] that | |
614 | you might need to interact with in an operator expression is (cheaply) | |
615 | default-constructible. You can use [^other<T>()] in place of an actual | |
616 | [^T] instance when writing "self expressions". | |
617 | ||
618 | [h2 Special Methods] | |
619 | ||
620 | Python has a few more ['Special Methods]. Boost.Python supports all of the | |
621 | standard special method names supported by real Python class instances. A | |
622 | similar set of intuitive interfaces can also be used to wrap C++ functions | |
623 | that correspond to these Python ['special functions]. Example: | |
624 | ||
625 | class Rational | |
626 | { public: operator double() const; }; | |
627 | ||
628 | Rational pow(Rational, Rational); | |
629 | Rational abs(Rational); | |
630 | ostream& operator<<(ostream&,Rational); | |
631 | ||
632 | class_<Rational>("Rational") | |
633 | .def(float_(self)) // __float__ | |
634 | .def(pow(self, other<Rational>)) // __pow__ | |
635 | .def(abs(self)) // __abs__ | |
636 | .def(str(self)) // __str__ | |
637 | ; | |
638 | ||
639 | Need we say more? | |
640 | ||
641 | [note What is the business of `operator<<`? | |
642 | Well, the method `str` requires the `operator<<` to do its work (i.e. | |
643 | `operator<<` is used by the method defined by `def(str(self))`.] | |
644 | ||
645 | [endsect] | |
646 | [endsect] [/ Exposing Classes ] | |
647 | ||
648 | [section Functions] | |
649 | ||
650 | In this chapter, we'll look at Boost.Python powered functions in closer | |
651 | detail. We will see some facilities to make exposing C++ functions to | |
652 | Python safe from potential pifalls such as dangling pointers and | |
653 | references. We will also see facilities that will make it even easier for | |
654 | us to expose C++ functions that take advantage of C++ features such as | |
655 | overloading and default arguments. | |
656 | ||
657 | [:['Read on...]] | |
658 | ||
659 | But before you do, you might want to fire up Python 2.2 or later and type | |
660 | [^>>> import this]. | |
661 | ||
662 | [pre | |
663 | >>> import this | |
664 | The Zen of Python, by Tim Peters | |
665 | Beautiful is better than ugly. | |
666 | Explicit is better than implicit. | |
667 | Simple is better than complex. | |
668 | Complex is better than complicated. | |
669 | Flat is better than nested. | |
670 | Sparse is better than dense. | |
671 | Readability counts. | |
672 | Special cases aren't special enough to break the rules. | |
673 | Although practicality beats purity. | |
674 | Errors should never pass silently. | |
675 | Unless explicitly silenced. | |
676 | In the face of ambiguity, refuse the temptation to guess. | |
677 | There should be one-- and preferably only one --obvious way to do it | |
678 | Although that way may not be obvious at first unless you're Dutch. | |
679 | Now is better than never. | |
680 | Although never is often better than *right* now. | |
681 | If the implementation is hard to explain, it's a bad idea. | |
682 | If the implementation is easy to explain, it may be a good idea. | |
683 | Namespaces are one honking great idea -- let's do more of those! | |
684 | ] | |
685 | ||
686 | [section Call Policies] | |
687 | ||
688 | In C++, we often deal with arguments and return types such as pointers | |
689 | and references. Such primitive types are rather, ummmm, low level and | |
690 | they really don't tell us much. At the very least, we don't know the | |
691 | owner of the pointer or the referenced object. No wonder languages | |
692 | such as Java and Python never deal with such low level entities. In | |
693 | C++, it's usually considered a good practice to use smart pointers | |
694 | which exactly describe ownership semantics. Still, even good C++ | |
695 | interfaces use raw references and pointers sometimes, so Boost.Python | |
696 | must deal with them. To do this, it may need your help. Consider the | |
697 | following C++ function: | |
698 | ||
699 | X& f(Y& y, Z* z); | |
700 | ||
701 | How should the library wrap this function? A naive approach builds a | |
702 | Python X object around result reference. This strategy might or might | |
703 | not work out. Here's an example where it didn't | |
704 | ||
705 | >>> x = f(y, z) # x refers to some C++ X | |
706 | >>> del y | |
707 | >>> x.some_method() # CRASH! | |
708 | ||
709 | What's the problem? | |
710 | ||
711 | Well, what if f() was implemented as shown below: | |
712 | ||
713 | X& f(Y& y, Z* z) | |
714 | { | |
715 | y.z = z; | |
716 | return y.x; | |
717 | } | |
718 | ||
719 | The problem is that the lifetime of result X& is tied to the lifetime | |
720 | of y, because the f() returns a reference to a member of the y | |
721 | object. This idiom is is not uncommon and perfectly acceptable in the | |
722 | context of C++. However, Python users should not be able to crash the | |
723 | system just by using our C++ interface. In this case deleting y will | |
724 | invalidate the reference to X. We have a dangling reference. | |
725 | ||
726 | Here's what's happening: | |
727 | ||
728 | # [^f] is called passing in a reference to [^y] and a pointer to [^z] | |
729 | # A reference to [^y.x] is returned | |
730 | # [^y] is deleted. [^x] is a dangling reference | |
731 | # [^x.some_method()] is called | |
732 | # [*BOOM!] | |
733 | ||
734 | We could copy result into a new object: | |
735 | ||
736 | [python] | |
737 | ||
738 | >>> f(y, z).set(42) # Result disappears | |
739 | >>> y.x.get() # No crash, but still bad | |
740 | 3.14 | |
741 | ||
742 | This is not really our intent of our C++ interface. We've broken our | |
743 | promise that the Python interface should reflect the C++ interface as | |
744 | closely as possible. | |
745 | ||
746 | Our problems do not end there. Suppose Y is implemented as follows: | |
747 | ||
748 | [c++] | |
749 | ||
750 | struct Y | |
751 | { | |
752 | X x; Z* z; | |
753 | int z_value() { return z->value(); } | |
754 | }; | |
755 | ||
756 | Notice that the data member [^z] is held by class Y using a raw | |
757 | pointer. Now we have a potential dangling pointer problem inside Y: | |
758 | ||
759 | >>> x = f(y, z) # y refers to z | |
760 | >>> del z # Kill the z object | |
761 | >>> y.z_value() # CRASH! | |
762 | ||
763 | For reference, here's the implementation of [^f] again: | |
764 | ||
765 | X& f(Y& y, Z* z) | |
766 | { | |
767 | y.z = z; | |
768 | return y.x; | |
769 | } | |
770 | ||
771 | Here's what's happening: | |
772 | ||
773 | # [^f] is called passing in a reference to [^y] and a pointer to [^z] | |
774 | # A pointer to [^z] is held by [^y] | |
775 | # A reference to [^y.x] is returned | |
776 | # [^z] is deleted. [^y.z] is a dangling pointer | |
777 | # [^y.z_value()] is called | |
778 | # [^z->value()] is called | |
779 | # [*BOOM!] | |
780 | ||
781 | [h2 Call Policies] | |
782 | ||
783 | Call Policies may be used in situations such as the example detailed above. | |
784 | In our example, [^return_internal_reference] and [^with_custodian_and_ward] | |
785 | are our friends: | |
786 | ||
787 | def("f", f, | |
788 | return_internal_reference<1, | |
789 | with_custodian_and_ward<1, 2> >()); | |
790 | ||
791 | What are the [^1] and [^2] parameters, you ask? | |
792 | ||
793 | return_internal_reference<1 | |
794 | ||
795 | Informs Boost.Python that the first argument, in our case [^Y& y], is the | |
796 | owner of the returned reference: [^X&]. The "[^1]" simply specifies the | |
797 | first argument. In short: "return an internal reference [^X&] owned by the | |
798 | 1st argument [^Y& y]". | |
799 | ||
800 | with_custodian_and_ward<1, 2> | |
801 | ||
802 | Informs Boost.Python that the lifetime of the argument indicated by ward | |
803 | (i.e. the 2nd argument: [^Z* z]) is dependent on the lifetime of the | |
804 | argument indicated by custodian (i.e. the 1st argument: [^Y& y]). | |
805 | ||
806 | It is also important to note that we have defined two policies above. Two | |
807 | or more policies can be composed by chaining. Here's the general syntax: | |
808 | ||
809 | policy1<args..., | |
810 | policy2<args..., | |
811 | policy3<args...> > > | |
812 | ||
813 | Here is the list of predefined call policies. A complete reference detailing | |
814 | these can be found [@../reference/function_invocation_and_creation/models_of_callpolicies.html here]. | |
815 | ||
816 | * [*with_custodian_and_ward]: Ties lifetimes of the arguments | |
817 | * [*with_custodian_and_ward_postcall]: Ties lifetimes of the arguments and results | |
818 | * [*return_internal_reference]: Ties lifetime of one argument to that of result | |
819 | * [*return_value_policy<T> with T one of:] | |
820 | * [*reference_existing_object]: naive (dangerous) approach | |
821 | * [*copy_const_reference]: Boost.Python v1 approach | |
822 | * [*copy_non_const_reference]: | |
823 | * [*manage_new_object]: Adopt a pointer and hold the instance | |
824 | ||
825 | [blurb :-) [*Remember the Zen, Luke:] | |
826 | ||
827 | "Explicit is better than implicit" | |
828 | ||
829 | "In the face of ambiguity, refuse the temptation to guess" | |
830 | ] | |
831 | ||
832 | [endsect] | |
833 | [section Overloading] | |
834 | ||
835 | The following illustrates a scheme for manually wrapping an overloaded | |
836 | member functions. Of course, the same technique can be applied to wrapping | |
837 | overloaded non-member functions. | |
838 | ||
839 | We have here our C++ class: | |
840 | ||
841 | struct X | |
842 | { | |
843 | bool f(int a) | |
844 | { | |
845 | return true; | |
846 | } | |
847 | ||
848 | bool f(int a, double b) | |
849 | { | |
850 | return true; | |
851 | } | |
852 | ||
853 | bool f(int a, double b, char c) | |
854 | { | |
855 | return true; | |
856 | } | |
857 | ||
858 | int f(int a, int b, int c) | |
859 | { | |
860 | return a + b + c; | |
861 | }; | |
862 | }; | |
863 | ||
864 | Class X has 4 overloaded functions. We will start by introducing some | |
865 | member function pointer variables: | |
866 | ||
867 | bool (X::*fx1)(int) = &X::f; | |
868 | bool (X::*fx2)(int, double) = &X::f; | |
869 | bool (X::*fx3)(int, double, char)= &X::f; | |
870 | int (X::*fx4)(int, int, int) = &X::f; | |
871 | ||
872 | With these in hand, we can proceed to define and wrap this for Python: | |
873 | ||
874 | .def("f", fx1) | |
875 | .def("f", fx2) | |
876 | .def("f", fx3) | |
877 | .def("f", fx4) | |
878 | ||
879 | [endsect] | |
880 | [section Default Arguments] | |
881 | ||
882 | Boost.Python wraps (member) function pointers. Unfortunately, C++ function | |
883 | pointers carry no default argument info. Take a function [^f] with default | |
884 | arguments: | |
885 | ||
886 | int f(int, double = 3.14, char const* = "hello"); | |
887 | ||
888 | But the type of a pointer to the function [^f] has no information | |
889 | about its default arguments: | |
890 | ||
891 | int(*g)(int,double,char const*) = f; // defaults lost! | |
892 | ||
893 | When we pass this function pointer to the [^def] function, there is no way | |
894 | to retrieve the default arguments: | |
895 | ||
896 | def("f", f); // defaults lost! | |
897 | ||
898 | Because of this, when wrapping C++ code, we had to resort to manual | |
899 | wrapping as outlined in the [link tutorial.functions.overloading previous section], or | |
900 | writing thin wrappers: | |
901 | ||
902 | // write "thin wrappers" | |
903 | int f1(int x) { return f(x); } | |
904 | int f2(int x, double y) { return f(x,y); } | |
905 | ||
906 | /*...*/ | |
907 | ||
908 | // in module init | |
909 | def("f", f); // all arguments | |
910 | def("f", f2); // two arguments | |
911 | def("f", f1); // one argument | |
912 | ||
913 | When you want to wrap functions (or member functions) that either: | |
914 | ||
915 | * have default arguments, or | |
916 | * are overloaded with a common sequence of initial arguments | |
917 | ||
918 | [h2 BOOST_PYTHON_FUNCTION_OVERLOADS] | |
919 | ||
920 | Boost.Python now has a way to make it easier. For instance, given a function: | |
921 | ||
922 | int foo(int a, char b = 1, unsigned c = 2, double d = 3) | |
923 | { | |
924 | /*...*/ | |
925 | } | |
926 | ||
927 | The macro invocation: | |
928 | ||
929 | BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4) | |
930 | ||
931 | will automatically create the thin wrappers for us. This macro will create | |
932 | a class [^foo_overloads] that can be passed on to [^def(...)]. The third | |
933 | and fourth macro argument are the minimum arguments and maximum arguments, | |
934 | respectively. In our [^foo] function the minimum number of arguments is 1 | |
935 | and the maximum number of arguments is 4. The [^def(...)] function will | |
936 | automatically add all the foo variants for us: | |
937 | ||
938 | def("foo", foo, foo_overloads()); | |
939 | ||
940 | [h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] | |
941 | ||
942 | Objects here, objects there, objects here there everywhere. More frequently | |
943 | than anything else, we need to expose member functions of our classes to | |
944 | Python. Then again, we have the same inconveniences as before when default | |
945 | arguments or overloads with a common sequence of initial arguments come | |
946 | into play. Another macro is provided to make this a breeze. | |
947 | ||
948 | Like [^BOOST_PYTHON_FUNCTION_OVERLOADS], | |
949 | [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] may be used to automatically create | |
950 | the thin wrappers for wrapping member functions. Let's have an example: | |
951 | ||
952 | struct george | |
953 | { | |
954 | void | |
955 | wack_em(int a, int b = 0, char c = 'x') | |
956 | { | |
957 | /*...*/ | |
958 | } | |
959 | }; | |
960 | ||
961 | The macro invocation: | |
962 | ||
963 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3) | |
964 | ||
965 | will generate a set of thin wrappers for george's [^wack_em] member function | |
966 | accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and | |
967 | fourth macro argument). The thin wrappers are all enclosed in a class named | |
968 | [^george_overloads] that can then be used as an argument to [^def(...)]: | |
969 | ||
970 | .def("wack_em", &george::wack_em, george_overloads()); | |
971 | ||
972 | See the [@../reference/function_invocation_and_creation/boost_python_overloads_hpp.html#function_invocation_and_creation.boost_python_overloads_hpp.macros overloads reference] | |
973 | for details. | |
974 | ||
975 | [h2 init and optional] | |
976 | ||
977 | A similar facility is provided for class constructors, again, with | |
978 | default arguments or a sequence of overloads. Remember [^init<...>]? For example, | |
979 | given a class X with a constructor: | |
980 | ||
981 | struct X | |
982 | { | |
983 | X(int a, char b = 'D', std::string c = "constructor", double d = 0.0); | |
984 | /*...*/ | |
985 | } | |
986 | ||
987 | You can easily add this constructor to Boost.Python in one shot: | |
988 | ||
989 | .def(init<int, optional<char, std::string, double> >()) | |
990 | ||
991 | Notice the use of [^init<...>] and [^optional<...>] to signify the default | |
992 | (optional arguments). | |
993 | ||
994 | [endsect] | |
995 | [section Auto-Overloading] | |
996 | ||
997 | It was mentioned in passing in the previous section that | |
998 | [^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] | |
999 | can also be used for overloaded functions and member functions with a | |
1000 | common sequence of initial arguments. Here is an example: | |
1001 | ||
1002 | void foo() | |
1003 | { | |
1004 | /*...*/ | |
1005 | } | |
1006 | ||
1007 | void foo(bool a) | |
1008 | { | |
1009 | /*...*/ | |
1010 | } | |
1011 | ||
1012 | void foo(bool a, int b) | |
1013 | { | |
1014 | /*...*/ | |
1015 | } | |
1016 | ||
1017 | void foo(bool a, int b, char c) | |
1018 | { | |
1019 | /*...*/ | |
1020 | } | |
1021 | ||
1022 | Like in the previous section, we can generate thin wrappers for these | |
1023 | overloaded functions in one-shot: | |
1024 | ||
1025 | BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3) | |
1026 | ||
1027 | Then... | |
1028 | ||
1029 | .def("foo", (void(*)(bool, int, char))0, foo_overloads()); | |
1030 | ||
1031 | Notice though that we have a situation now where we have a minimum of zero | |
1032 | (0) arguments and a maximum of 3 arguments. | |
1033 | ||
1034 | [h2 Manual Wrapping] | |
1035 | ||
1036 | It is important to emphasize however that [*the overloaded functions must | |
1037 | have a common sequence of initial arguments]. Otherwise, our scheme above | |
1038 | will not work. If this is not the case, we have to wrap our functions | |
1039 | [link tutorial.functions.overloading manually]. | |
1040 | ||
1041 | Actually, we can mix and match manual wrapping of overloaded functions and | |
1042 | automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and | |
1043 | its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example | |
1044 | presented in the section [link tutorial.functions.overloading on overloading], since the | |
1045 | first 4 overload functins have a common sequence of initial arguments, we | |
1046 | can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the | |
1047 | first three of the [^def]s and manually wrap just the last. Here's | |
1048 | how we'll do this: | |
1049 | ||
1050 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4) | |
1051 | ||
1052 | Create a member function pointers as above for both X::f overloads: | |
1053 | ||
1054 | bool (X::*fx1)(int, double, char) = &X::f; | |
1055 | int (X::*fx2)(int, int, int) = &X::f; | |
1056 | ||
1057 | Then... | |
1058 | ||
1059 | .def("f", fx1, xf_overloads()); | |
1060 | .def("f", fx2) | |
1061 | ||
1062 | [endsect] | |
1063 | [endsect] [/ Functions ] | |
1064 | ||
1065 | [section:object Object Interface] | |
1066 | ||
1067 | Python is dynamically typed, unlike C++ which is statically typed. Python | |
1068 | variables may hold an integer, a float, list, dict, tuple, str, long etc., | |
1069 | among other things. In the viewpoint of Boost.Python and C++, these | |
1070 | Pythonic variables are just instances of class [^object]. We will see in | |
1071 | this chapter how to deal with Python objects. | |
1072 | ||
1073 | As mentioned, one of the goals of Boost.Python is to provide a | |
1074 | bidirectional mapping between C++ and Python while maintaining the Python | |
1075 | feel. Boost.Python C++ [^object]s are as close as possible to Python. This | |
1076 | should minimize the learning curve significantly. | |
1077 | ||
1078 | [$../images/python.png] | |
1079 | ||
1080 | [section Basic Interface] | |
1081 | ||
1082 | Class [^object] wraps [^PyObject*]. All the intricacies of dealing with | |
1083 | [^PyObject]s such as managing reference counting are handled by the | |
1084 | [^object] class. C++ object interoperability is seamless. Boost.Python C++ | |
1085 | [^object]s can in fact be explicitly constructed from any C++ object. | |
1086 | ||
1087 | To illustrate, this Python code snippet: | |
1088 | ||
1089 | [python] | |
1090 | ||
1091 | def f(x, y): | |
1092 | if (y == 'foo'): | |
1093 | x[3:7] = 'bar' | |
1094 | else: | |
1095 | x.items += y(3, x) | |
1096 | return x | |
1097 | ||
1098 | def getfunc(): | |
1099 | return f; | |
1100 | ||
1101 | Can be rewritten in C++ using Boost.Python facilities this way: | |
1102 | ||
1103 | [c++] | |
1104 | ||
1105 | object f(object x, object y) { | |
1106 | if (y == "foo") | |
1107 | x.slice(3,7) = "bar"; | |
1108 | else | |
1109 | x.attr("items") += y(3, x); | |
1110 | return x; | |
1111 | } | |
1112 | object getfunc() { | |
1113 | return object(f); | |
1114 | } | |
1115 | ||
1116 | Apart from cosmetic differences due to the fact that we are writing the | |
1117 | code in C++, the look and feel should be immediately apparent to the Python | |
1118 | coder. | |
1119 | ||
1120 | [endsect] | |
1121 | [section Derived Object types] | |
1122 | ||
1123 | Boost.Python comes with a set of derived [^object] types corresponding to | |
1124 | that of Python's: | |
1125 | ||
1126 | * list | |
1127 | * dict | |
1128 | * tuple | |
1129 | * str | |
1130 | * long_ | |
1131 | * enum | |
1132 | ||
1133 | These derived [^object] types act like real Python types. For instance: | |
1134 | ||
1135 | str(1) ==> "1" | |
1136 | ||
1137 | Wherever appropriate, a particular derived [^object] has corresponding | |
1138 | Python type's methods. For instance, [^dict] has a [^keys()] method: | |
1139 | ||
1140 | d.keys() | |
1141 | ||
1142 | [^make_tuple] is provided for declaring ['tuple literals]. Example: | |
1143 | ||
1144 | make_tuple(123, 'D', "Hello, World", 0.0); | |
1145 | ||
1146 | In C++, when Boost.Python [^object]s are used as arguments to functions, | |
1147 | subtype matching is required. For example, when a function [^f], as | |
1148 | declared below, is wrapped, it will only accept instances of Python's | |
1149 | [^str] type and subtypes. | |
1150 | ||
1151 | void f(str name) | |
1152 | { | |
1153 | object n2 = name.attr("upper")(); // NAME = name.upper() | |
1154 | str NAME = name.upper(); // better | |
1155 | object msg = "%s is bigger than %s" % make_tuple(NAME,name); | |
1156 | } | |
1157 | ||
1158 | In finer detail: | |
1159 | ||
1160 | str NAME = name.upper(); | |
1161 | ||
1162 | Illustrates that we provide versions of the str type's methods as C++ | |
1163 | member functions. | |
1164 | ||
1165 | object msg = "%s is bigger than %s" % make_tuple(NAME,name); | |
1166 | ||
1167 | Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z] | |
1168 | in Python, which is useful since there's no easy way to do that in std C++. | |
1169 | ||
1170 | [blurb | |
1171 | __alert__ [*Beware] the common pitfall of forgetting that the constructors | |
1172 | of most of Python's mutable types make copies, just as in Python. | |
1173 | ] | |
1174 | ||
1175 | Python: | |
1176 | [python] | |
1177 | ||
1178 | >>> d = dict(x.__dict__) # copies x.__dict__ | |
1179 | >>> d['whatever'] = 3 # modifies the copy | |
1180 | ||
1181 | C++: | |
1182 | [c++] | |
1183 | ||
1184 | dict d(x.attr("__dict__")); // copies x.__dict__ | |
1185 | d['whatever'] = 3; // modifies the copy | |
1186 | ||
1187 | [h2 class_<T> as objects] | |
1188 | ||
1189 | Due to the dynamic nature of Boost.Python objects, any [^class_<T>] may | |
1190 | also be one of these types! The following code snippet wraps the class | |
1191 | (type) object. | |
1192 | ||
1193 | We can use this to create wrapped instances. Example: | |
1194 | ||
1195 | object vec345 = ( | |
1196 | class_<Vec2>("Vec2", init<double, double>()) | |
1197 | .def_readonly("length", &Point::length) | |
1198 | .def_readonly("angle", &Point::angle) | |
1199 | )(3.0, 4.0); | |
1200 | ||
1201 | assert(vec345.attr("length") == 5.0); | |
1202 | ||
1203 | [endsect] | |
1204 | [section Extracting C++ objects] | |
1205 | ||
1206 | At some point, we will need to get C++ values out of object instances. This | |
1207 | can be achieved with the [^extract<T>] function. Consider the following: | |
1208 | ||
1209 | double x = o.attr("length"); // compile error | |
1210 | ||
1211 | In the code above, we got a compiler error because Boost.Python | |
1212 | [^object] can't be implicitly converted to [^double]s. Instead, what | |
1213 | we wanted to do above can be achieved by writing: | |
1214 | ||
1215 | double l = extract<double>(o.attr("length")); | |
1216 | Vec2& v = extract<Vec2&>(o); | |
1217 | assert(l == v.length()); | |
1218 | ||
1219 | The first line attempts to extract the "length" attribute of the Boost.Python | |
1220 | [^object]. The second line attempts to ['extract] the [^Vec2] object from held | |
1221 | by the Boost.Python [^object]. | |
1222 | ||
1223 | Take note that we said "attempt to" above. What if the Boost.Python [^object] | |
1224 | does not really hold a [^Vec2] type? This is certainly a possibility considering | |
1225 | the dynamic nature of Python [^object]s. To be on the safe side, if the C++ type | |
1226 | can't be extracted, an appropriate exception is thrown. To avoid an exception, | |
1227 | we need to test for extractibility: | |
1228 | ||
1229 | extract<Vec2&> x(o); | |
1230 | if (x.check()) { | |
1231 | Vec2& v = x(); ... | |
1232 | ||
1233 | __tip__ The astute reader might have noticed that the [^extract<T>] | |
1234 | facility in fact solves the mutable copying problem: | |
1235 | ||
1236 | dict d = extract<dict>(x.attr("__dict__")); | |
1237 | d["whatever"] = 3; // modifies x.__dict__ ! | |
1238 | ||
1239 | ||
1240 | [endsect] | |
1241 | [section Enums] | |
1242 | ||
1243 | Boost.Python has a nifty facility to capture and wrap C++ enums. While | |
1244 | Python has no [^enum] type, we'll often want to expose our C++ enums to | |
1245 | Python as an [^int]. Boost.Python's enum facility makes this easy while | |
1246 | taking care of the proper conversions from Python's dynamic typing to C++'s | |
1247 | strong static typing (in C++, ints cannot be implicitly converted to | |
1248 | enums). To illustrate, given a C++ enum: | |
1249 | ||
1250 | enum choice { red, blue }; | |
1251 | ||
1252 | the construct: | |
1253 | ||
1254 | enum_<choice>("choice") | |
1255 | .value("red", red) | |
1256 | .value("blue", blue) | |
1257 | ; | |
1258 | ||
1259 | can be used to expose to Python. The new enum type is created in the | |
1260 | current [^scope()], which is usually the current module. The snippet above | |
1261 | creates a Python class derived from Python's [^int] type which is | |
1262 | associated with the C++ type passed as its first parameter. | |
1263 | ||
1264 | [note [*what is a scope?] | |
1265 | ||
1266 | The scope is a class that has an associated global Python object which | |
1267 | controls the Python namespace in which new extension classes and wrapped | |
1268 | functions will be defined as attributes. Details can be found | |
1269 | [@../reference/high_level_components/boost_python_scope_hpp.html#high_level_components.boost_python_scope_hpp.class_scope here].] | |
1270 | ||
1271 | You can access those values in Python as | |
1272 | ||
1273 | [python] | |
1274 | ||
1275 | >>> my_module.choice.red | |
1276 | my_module.choice.red | |
1277 | ||
1278 | where my_module is the module where the enum is declared. You can also | |
1279 | create a new scope around a class: | |
1280 | ||
1281 | [c++] | |
1282 | ||
1283 | scope in_X = class_<X>("X") | |
1284 | .def( ... ) | |
1285 | .def( ... ) | |
1286 | ; | |
1287 | ||
1288 | // Expose X::nested as X.nested | |
1289 | enum_<X::nested>("nested") | |
1290 | .value("red", red) | |
1291 | .value("blue", blue) | |
1292 | ; | |
1293 | ||
1294 | [def Py_Initialize [@http://www.python.org/doc/current/api/initialization.html#l2h-652 Py_Initialize]] | |
1295 | [def Py_Finalize [@http://www.python.org/doc/current/api/initialization.html#l2h-656 Py_Finalize]] | |
1296 | [def Py_XINCREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-65 Py_XINCREF]] | |
1297 | [def Py_XDECREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-67 Py_XDECREF]] | |
1298 | [def PyImport_AppendInittab [@http://www.python.org/doc/current/api/importing.html#l2h-137 PyImport_AppendInittab]] | |
1299 | [def PyImport_AddModule [@http://www.python.org/doc/current/api/importing.html#l2h-125 PyImport_AddModule]] | |
1300 | [def PyModule_New [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-591 PyModule_New]] | |
1301 | [def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]] | |
1302 | ||
1303 | [endsect] | |
1304 | ||
1305 | [section:creating_python_object Creating `boost::python::object` from `PyObject*`] | |
1306 | ||
1307 | When you want a `boost::python::object` to manage a pointer to `PyObject*` pyobj one does: | |
1308 | ||
1309 | boost::python::object o(boost::python::handle<>(pyobj)); | |
1310 | ||
1311 | In this case, the `o` object, manages the `pyobj`, it won’t increase the reference count on construction. | |
1312 | ||
1313 | Otherwise, to use a borrowed reference: | |
1314 | ||
1315 | boost::python::object o(boost::python::handle<>(boost::python::borrowed(pyobj))); | |
1316 | ||
1317 | In this case, `Py_INCREF` is called, so `pyobj` is not destructed when object o goes out of scope. | |
1318 | ||
1319 | [endsect] [/ creating_python_object ] | |
1320 | ||
1321 | [endsect] [/ Object Interface] | |
1322 | ||
1323 | [section Embedding] | |
1324 | ||
1325 | By now you should know how to use Boost.Python to call your C++ code from | |
1326 | Python. However, sometimes you may need to do the reverse: call Python code | |
1327 | from the C++-side. This requires you to ['embed] the Python interpreter | |
1328 | into your C++ program. | |
1329 | ||
1330 | Currently, Boost.Python does not directly support everything you'll need | |
1331 | when embedding. Therefore you'll need to use the | |
1332 | [@http://www.python.org/doc/current/api/api.html Python/C API] to fill in | |
1333 | the gaps. However, Boost.Python already makes embedding a lot easier and, | |
1334 | in a future version, it may become unnecessary to touch the Python/C API at | |
1335 | all. So stay tuned... :-) | |
1336 | ||
1337 | [h2 Building embedded programs] | |
1338 | ||
1339 | To be able to embed python into your programs, you have to link to | |
1340 | both Boost.Python's as well as Python's own runtime library. | |
1341 | ||
1342 | Boost.Python's library comes in two variants. Both are located | |
1343 | in Boost's [^/libs/python/build/bin-stage] subdirectory. On Windows, the | |
1344 | variants are called [^boost_python.lib] (for release builds) and | |
1345 | [^boost_python_debug.lib] (for debugging). If you can't find the libraries, | |
1346 | you probably haven't built Boost.Python yet. See | |
1347 | [@../../../building.html Building and Testing] on how to do this. | |
1348 | ||
1349 | Python's library can be found in the [^/libs] subdirectory of | |
1350 | your Python directory. On Windows it is called pythonXY.lib where X.Y is | |
1351 | your major Python version number. | |
1352 | ||
1353 | Additionally, Python's [^/include] subdirectory has to be added to your | |
1354 | include path. | |
1355 | ||
1356 | In a Jamfile, all the above boils down to: | |
1357 | ||
1358 | [pre | |
1359 | projectroot c:\projects\embedded_program ; # location of the program | |
1360 | ||
1361 | # bring in the rules for python | |
1362 | SEARCH on python.jam = $(BOOST_BUILD_PATH) ; | |
1363 | include python.jam ; | |
1364 | ||
1365 | exe embedded_program # name of the executable | |
1366 | : #sources | |
1367 | embedded_program.cpp | |
1368 | : # requirements | |
1369 | <find-library>boost_python <library-path>c:\boost\libs\python | |
1370 | $(PYTHON_PROPERTIES) | |
1371 | <library-path>$(PYTHON_LIB_PATH) | |
1372 | <find-library>$(PYTHON_EMBEDDED_LIBRARY) ; | |
1373 | ] | |
1374 | ||
1375 | [h2 Getting started] | |
1376 | ||
1377 | Being able to build is nice, but there is nothing to build yet. Embedding | |
1378 | the Python interpreter into one of your C++ programs requires these 4 | |
1379 | steps: | |
1380 | ||
1381 | # '''#include''' [^<boost/python.hpp>] | |
1382 | ||
1383 | # Call Py_Initialize() to start the interpreter and create the [^__main__] module. | |
1384 | ||
1385 | # Call other Python C API routines to use the interpreter. | |
1386 | ||
1387 | [/ # Call Py_Finalize() to stop the interpreter and release its resources.] | |
1388 | ||
1389 | [note [*Note that at this time you must not call Py_Finalize() to stop the | |
1390 | interpreter. This may be fixed in a future version of boost.python.] | |
1391 | ] | |
1392 | ||
1393 | (Of course, there can be other C++ code between all of these steps.) | |
1394 | ||
1395 | [:['[*Now that we can embed the interpreter in our programs, lets see how to put it to use...]]] | |
1396 | ||
1397 | [section Using the interpreter] | |
1398 | ||
1399 | As you probably already know, objects in Python are reference-counted. | |
1400 | Naturally, the [^PyObject]s of the Python C API are also reference-counted. | |
1401 | There is a difference however. While the reference-counting is fully | |
1402 | automatic in Python, the Python C API requires you to do it | |
1403 | [@http://www.python.org/doc/current/c-api/refcounting.html by hand]. This is | |
1404 | messy and especially hard to get right in the presence of C++ exceptions. | |
1405 | Fortunately Boost.Python provides the [@../reference/utility_and_infrastructure/boost_python_handle_hpp.html#utility_and_infrastructure.boost_python_handle_hpp.class_template_handle handle] and | |
1406 | [@../reference/object_wrappers/boost_python_object_hpp.html#object_wrappers.boost_python_object_hpp.class_object object] class templates to automate the process. | |
1407 | ||
1408 | [h2 Running Python code] | |
1409 | ||
1410 | Boost.python provides three related functions to run Python code from C++. | |
1411 | ||
1412 | object eval(str expression, object globals = object(), object locals = object()) | |
1413 | object exec(str code, object globals = object(), object locals = object()) | |
1414 | object exec_file(str filename, object globals = object(), object locals = object()) | |
1415 | ||
1416 | eval evaluates the given expression and returns the resulting value. | |
1417 | exec executes the given code (typically a set of statements) returning the result, | |
1418 | and exec_file executes the code contained in the given file. | |
1419 | ||
1420 | The [^globals] and [^locals] parameters are Python dictionaries | |
1421 | containing the globals and locals of the context in which to run the code. | |
1422 | For most intents and purposes you can use the namespace dictionary of the | |
1423 | [^__main__] module for both parameters. | |
1424 | ||
1425 | Boost.python provides a function to import a module: | |
1426 | ||
1427 | object import(str name) | |
1428 | ||
1429 | import imports a python module (potentially loading it into the running process | |
1430 | first), and returns it. | |
1431 | ||
1432 | Let's import the [^__main__] module and run some Python code in its namespace: | |
1433 | ||
1434 | object main_module = import("__main__"); | |
1435 | object main_namespace = main_module.attr("__dict__"); | |
1436 | ||
1437 | object ignored = exec("hello = file('hello.txt', 'w')\n" | |
1438 | "hello.write('Hello world!')\n" | |
1439 | "hello.close()", | |
1440 | main_namespace); | |
1441 | ||
1442 | This should create a file called 'hello.txt' in the current directory | |
1443 | containing a phrase that is well-known in programming circles. | |
1444 | ||
1445 | [h2 Manipulating Python objects] | |
1446 | ||
1447 | Often we'd like to have a class to manipulate Python objects. | |
1448 | But we have already seen such a class above, and in the | |
1449 | [link tutorial.object previous section]: the aptly named [^object] class | |
1450 | and its derivatives. We've already seen that they can be constructed from | |
1451 | a [^handle]. The following examples should further illustrate this fact: | |
1452 | ||
1453 | object main_module = import("__main__"); | |
1454 | object main_namespace = main_module.attr("__dict__"); | |
1455 | object ignored = exec("result = 5 ** 2", main_namespace); | |
1456 | int five_squared = extract<int>(main_namespace["result"]); | |
1457 | ||
1458 | Here we create a dictionary object for the [^__main__] module's namespace. | |
1459 | Then we assign 5 squared to the result variable and read this variable from | |
1460 | the dictionary. Another way to achieve the same result is to use eval instead, | |
1461 | which returns the result directly: | |
1462 | ||
1463 | object result = eval("5 ** 2"); | |
1464 | int five_squared = extract<int>(result); | |
1465 | ||
1466 | [h2 Exception handling] | |
1467 | ||
1468 | If an exception occurs in the evaluation of the python expression, | |
1469 | [@../reference/high_level_components/boost_python_errors_hpp.html#high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set] is thrown: | |
1470 | ||
1471 | try | |
1472 | { | |
1473 | object result = eval("5/0"); | |
1474 | // execution will never get here: | |
1475 | int five_divided_by_zero = extract<int>(result); | |
1476 | } | |
1477 | catch(error_already_set const &) | |
1478 | { | |
1479 | // handle the exception in some way | |
1480 | } | |
1481 | ||
1482 | The [^error_already_set] exception class doesn't carry any information in itself. | |
1483 | To find out more about the Python exception that occurred, you need to use the | |
1484 | [@http://www.python.org/doc/api/exceptionHandling.html exception handling functions] | |
1485 | of the Python C API in your catch-statement. This can be as simple as calling | |
1486 | [@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to | |
1487 | print the exception's traceback to the console, or comparing the type of the | |
1488 | exception with those of the [@http://www.python.org/doc/api/standardExceptions.html | |
1489 | standard exceptions]: | |
1490 | ||
1491 | catch(error_already_set const &) | |
1492 | { | |
1493 | if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) | |
1494 | { | |
1495 | // handle ZeroDivisionError specially | |
1496 | } | |
1497 | else | |
1498 | { | |
1499 | // print all other errors to stderr | |
1500 | PyErr_Print(); | |
1501 | } | |
1502 | } | |
1503 | ||
1504 | (To retrieve even more information from the exception you can use some of the other | |
1505 | exception handling functions listed [@http://www.python.org/doc/api/exceptionHandling.html here].) | |
1506 | ||
1507 | [endsect] | |
1508 | [endsect] [/ Embedding] | |
1509 | ||
1510 | [section Iterators] | |
1511 | ||
1512 | In C++, and STL in particular, we see iterators everywhere. Python also has | |
1513 | iterators, but these are two very different beasts. | |
1514 | ||
1515 | [*C++ iterators:] | |
1516 | ||
1517 | * C++ has 5 type categories (random-access, bidirectional, forward, input, output) | |
1518 | * There are 2 Operation categories: reposition, access | |
1519 | * A pair of iterators is needed to represent a (first/last) range. | |
1520 | ||
1521 | [*Python Iterators:] | |
1522 | ||
1523 | * 1 category (forward) | |
1524 | * 1 operation category (next()) | |
1525 | * Raises StopIteration exception at end | |
1526 | ||
1527 | The typical Python iteration protocol: [^[*for y in x...]] is as follows: | |
1528 | ||
1529 | [python] | |
1530 | ||
1531 | iter = x.__iter__() # get iterator | |
1532 | try: | |
1533 | while 1: | |
1534 | y = iter.next() # get each item | |
1535 | ... # process y | |
1536 | except StopIteration: pass # iterator exhausted | |
1537 | ||
1538 | Boost.Python provides some mechanisms to make C++ iterators play along | |
1539 | nicely as Python iterators. What we need to do is to produce | |
1540 | appropriate `__iter__` function from C++ iterators that is compatible | |
1541 | with the Python iteration protocol. For example: | |
1542 | ||
1543 | [c++] | |
1544 | ||
1545 | object get_iterator = iterator<vector<int> >(); | |
1546 | object iter = get_iterator(v); | |
1547 | object first = iter.next(); | |
1548 | ||
1549 | Or for use in class_<>: | |
1550 | ||
1551 | .def("__iter__", iterator<vector<int> >()) | |
1552 | ||
1553 | [*range] | |
1554 | ||
1555 | We can create a Python savvy iterator using the range function: | |
1556 | ||
1557 | * range(start, finish) | |
1558 | * range<Policies,Target>(start, finish) | |
1559 | ||
1560 | Here, start/finish may be one of: | |
1561 | ||
1562 | * member data pointers | |
1563 | * member function pointers | |
1564 | * adaptable function object (use Target parameter) | |
1565 | ||
1566 | [*iterator] | |
1567 | ||
1568 | * iterator<T, Policies>() | |
1569 | ||
1570 | Given a container [^T], iterator is a shortcut that simply calls [^range] | |
1571 | with &T::begin, &T::end. | |
1572 | ||
1573 | Let's put this into action... Here's an example from some hypothetical | |
1574 | bogon Particle accelerator code: | |
1575 | ||
1576 | [python] | |
1577 | ||
1578 | f = Field() | |
1579 | for x in f.pions: | |
1580 | smash(x) | |
1581 | for y in f.bogons: | |
1582 | count(y) | |
1583 | ||
1584 | Now, our C++ Wrapper: | |
1585 | ||
1586 | [c++] | |
1587 | ||
1588 | class_<F>("Field") | |
1589 | .property("pions", range(&F::p_begin, &F::p_end)) | |
1590 | .property("bogons", range(&F::b_begin, &F::b_end)); | |
1591 | ||
1592 | [*stl_input_iterator] | |
1593 | ||
1594 | So far, we have seen how to expose C++ iterators and ranges to Python. | |
1595 | Sometimes we wish to go the other way, though: we'd like to pass a | |
1596 | Python sequence to an STL algorithm or use it to initialize an STL | |
1597 | container. We need to make a Python iterator look like an STL iterator. | |
1598 | For that, we use `stl_input_iterator<>`. Consider how we might | |
1599 | implement a function that exposes `std::list<int>::assign()` to | |
1600 | Python: | |
1601 | ||
1602 | [c++] | |
1603 | ||
1604 | template<typename T> | |
1605 | void list_assign(std::list<T>& l, object o) { | |
1606 | // Turn a Python sequence into an STL input range | |
1607 | stl_input_iterator<T> begin(o), end; | |
1608 | l.assign(begin, end); | |
1609 | } | |
1610 | ||
1611 | // Part of the wrapper for list<int> | |
1612 | class_<std::list<int> >("list_int") | |
1613 | .def("assign", &list_assign<int>) | |
1614 | // ... | |
1615 | ; | |
1616 | ||
1617 | Now in Python, we can assign any integer sequence to `list_int` objects: | |
1618 | ||
1619 | [python] | |
1620 | ||
1621 | x = list_int(); | |
1622 | x.assign([1,2,3,4,5]) | |
1623 | ||
1624 | [endsect] | |
1625 | [section:exception Exception Translation] | |
1626 | ||
1627 | All C++ exceptions must be caught at the boundary with Python code. This | |
1628 | boundary is the point where C++ meets Python. Boost.Python provides a | |
1629 | default exception handler that translates selected standard exceptions, | |
1630 | then gives up: | |
1631 | ||
1632 | raise RuntimeError, 'unidentifiable C++ Exception' | |
1633 | ||
1634 | Users may provide custom translation. Here's an example: | |
1635 | ||
1636 | struct PodBayDoorException; | |
1637 | void translator(PodBayDoorException const& x) { | |
1638 | PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave..."); | |
1639 | } | |
1640 | BOOST_PYTHON_MODULE(kubrick) { | |
1641 | register_exception_translator< | |
1642 | PodBayDoorException>(translator); | |
1643 | ... | |
1644 | ||
1645 | [endsect] | |
1646 | [section:techniques General Techniques] | |
1647 | ||
1648 | Here are presented some useful techniques that you can use while wrapping code with Boost.Python. | |
1649 | ||
1650 | [section Creating Packages] | |
1651 | ||
1652 | A Python package is a collection of modules that provide to the user a certain | |
1653 | functionality. If you're not familiar on how to create packages, a good | |
1654 | introduction to them is provided in the | |
1655 | [@http://www.python.org/doc/current/tut/node8.html Python Tutorial]. | |
1656 | ||
1657 | But we are wrapping C++ code, using Boost.Python. How can we provide a nice | |
1658 | package interface to our users? To better explain some concepts, let's work | |
1659 | with an example. | |
1660 | ||
1661 | We have a C++ library that works with sounds: reading and writing various | |
1662 | formats, applying filters to the sound data, etc. It is named (conveniently) | |
1663 | [^sounds]. Our library already has a neat C++ namespace hierarchy, like so: | |
1664 | ||
1665 | sounds::core | |
1666 | sounds::io | |
1667 | sounds::filters | |
1668 | ||
1669 | We would like to present this same hierarchy to the Python user, allowing him | |
1670 | to write code like this: | |
1671 | ||
1672 | import sounds.filters | |
1673 | sounds.filters.echo(...) # echo is a C++ function | |
1674 | ||
1675 | The first step is to write the wrapping code. We have to export each module | |
1676 | separately with Boost.Python, like this: | |
1677 | ||
1678 | /* file core.cpp */ | |
1679 | BOOST_PYTHON_MODULE(core) | |
1680 | { | |
1681 | /* export everything in the sounds::core namespace */ | |
1682 | ... | |
1683 | } | |
1684 | ||
1685 | /* file io.cpp */ | |
1686 | BOOST_PYTHON_MODULE(io) | |
1687 | { | |
1688 | /* export everything in the sounds::io namespace */ | |
1689 | ... | |
1690 | } | |
1691 | ||
1692 | /* file filters.cpp */ | |
1693 | BOOST_PYTHON_MODULE(filters) | |
1694 | { | |
1695 | /* export everything in the sounds::filters namespace */ | |
1696 | ... | |
1697 | } | |
1698 | ||
1699 | Compiling these files will generate the following Python extensions: | |
1700 | [^core.pyd], [^io.pyd] and [^filters.pyd]. | |
1701 | ||
1702 | [note The extension [^.pyd] is used for python extension modules, which | |
1703 | are just shared libraries. Using the default for your system, like [^.so] for | |
1704 | Unix and [^.dll] for Windows, works just as well.] | |
1705 | ||
1706 | Now, we create this directory structure for our Python package: | |
1707 | ||
1708 | [pre | |
1709 | sounds/ | |
1710 | \_\_init\_\_.py | |
1711 | core.pyd | |
1712 | filters.pyd | |
1713 | io.pyd | |
1714 | ] | |
1715 | ||
1716 | The file [^\_\_init\_\_.py] is what tells Python that the directory [^sounds/] is | |
1717 | actually a Python package. It can be a empty file, but can also perform some | |
1718 | magic, that will be shown later. | |
1719 | ||
1720 | Now our package is ready. All the user has to do is put [^sounds] into his | |
1721 | [@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] | |
1722 | and fire up the interpreter: | |
1723 | ||
1724 | [python] | |
1725 | ||
1726 | >>> import sounds.io | |
1727 | >>> import sounds.filters | |
1728 | >>> sound = sounds.io.open('file.mp3') | |
1729 | >>> new_sound = sounds.filters.echo(sound, 1.0) | |
1730 | ||
1731 | Nice heh? | |
1732 | ||
1733 | This is the simplest way to create hierarchies of packages, but it is not very | |
1734 | flexible. What if we want to add a ['pure] Python function to the filters | |
1735 | package, for instance, one that applies 3 filters in a sound object at once? | |
1736 | Sure, you can do this in C++ and export it, but why not do so in Python? You | |
1737 | don't have to recompile the extension modules, plus it will be easier to write | |
1738 | it. | |
1739 | ||
1740 | If we want this flexibility, we will have to complicate our package hierarchy a | |
1741 | little. First, we will have to change the name of the extension modules: | |
1742 | ||
1743 | [c++] | |
1744 | ||
1745 | /* file core.cpp */ | |
1746 | BOOST_PYTHON_MODULE(_core) | |
1747 | { | |
1748 | ... | |
1749 | /* export everything in the sounds::core namespace */ | |
1750 | } | |
1751 | ||
1752 | Note that we added an underscore to the module name. The filename will have to | |
1753 | be changed to [^_core.pyd] as well, and we do the same to the other extension modules. | |
1754 | Now, we change our package hierarchy like so: | |
1755 | ||
1756 | [pre | |
1757 | sounds/ | |
1758 | \_\_init\_\_.py | |
1759 | core/ | |
1760 | \_\_init\_\_.py | |
1761 | \_core.pyd | |
1762 | filters/ | |
1763 | \_\_init\_\_.py | |
1764 | \_filters.pyd | |
1765 | io/ | |
1766 | \_\_init\_\_.py | |
1767 | \_io.pyd | |
1768 | ] | |
1769 | ||
1770 | Note that we created a directory for each extension module, and added a | |
1771 | \_\_init\_\_.py to each one. But if we leave it that way, the user will have to | |
1772 | access the functions in the core module with this syntax: | |
1773 | ||
1774 | [python] | |
1775 | ||
1776 | >>> import sounds.core._core | |
1777 | >>> sounds.core._core.foo(...) | |
1778 | ||
1779 | which is not what we want. But here enters the [^\_\_init\_\_.py] magic: everything | |
1780 | that is brought to the [^\_\_init\_\_.py] namespace can be accessed directly by the | |
1781 | user. So, all we have to do is bring the entire namespace from [^_core.pyd] | |
1782 | to [^core/\_\_init\_\_.py]. So add this line of code to [^sounds/core/\_\_init\_\_.py]: | |
1783 | ||
1784 | from _core import * | |
1785 | ||
1786 | We do the same for the other packages. Now the user accesses the functions and | |
1787 | classes in the extension modules like before: | |
1788 | ||
1789 | >>> import sounds.filters | |
1790 | >>> sounds.filters.echo(...) | |
1791 | ||
1792 | with the additional benefit that we can easily add pure Python functions to | |
1793 | any module, in a way that the user can't tell the difference between a C++ | |
1794 | function and a Python function. Let's add a ['pure] Python function, | |
1795 | [^echo_noise], to the [^filters] package. This function applies both the | |
1796 | [^echo] and [^noise] filters in sequence in the given [^sound] object. We | |
1797 | create a file named [^sounds/filters/echo_noise.py] and code our function: | |
1798 | ||
1799 | import _filters | |
1800 | def echo_noise(sound): | |
1801 | s = _filters.echo(sound) | |
1802 | s = _filters.noise(sound) | |
1803 | return s | |
1804 | ||
1805 | Next, we add this line to [^sounds/filters/\_\_init\_\_.py]: | |
1806 | ||
1807 | from echo_noise import echo_noise | |
1808 | ||
1809 | And that's it. The user now accesses this function like any other function | |
1810 | from the [^filters] package: | |
1811 | ||
1812 | >>> import sounds.filters | |
1813 | >>> sounds.filters.echo_noise(...) | |
1814 | ||
1815 | [endsect] | |
1816 | [section Extending Wrapped Objects in Python] | |
1817 | ||
1818 | Thanks to Python's flexibility, you can easily add new methods to a class, | |
1819 | even after it was already created: | |
1820 | ||
1821 | >>> class C(object): pass | |
1822 | >>> | |
1823 | >>> # a regular function | |
1824 | >>> def C_str(self): return 'A C instance!' | |
1825 | >>> | |
1826 | >>> # now we turn it in a member function | |
1827 | >>> C.__str__ = C_str | |
1828 | >>> | |
1829 | >>> c = C() | |
1830 | >>> print c | |
1831 | A C instance! | |
1832 | >>> C_str(c) | |
1833 | A C instance! | |
1834 | ||
1835 | Yes, Python rox. :-) | |
1836 | ||
1837 | We can do the same with classes that were wrapped with Boost.Python. Suppose | |
1838 | we have a class [^point] in C++: | |
1839 | ||
1840 | [c++] | |
1841 | ||
1842 | class point {...}; | |
1843 | ||
1844 | BOOST_PYTHON_MODULE(_geom) | |
1845 | { | |
1846 | class_<point>("point")...; | |
1847 | } | |
1848 | ||
1849 | If we are using the technique from the previous session, | |
1850 | [link tutorial.techniques.creating_packages Creating Packages], we can code directly | |
1851 | into [^geom/\_\_init\_\_.py]: | |
1852 | ||
1853 | [python] | |
1854 | ||
1855 | from _geom import * | |
1856 | ||
1857 | # a regular function | |
1858 | def point_str(self): | |
1859 | return str((self.x, self.y)) | |
1860 | ||
1861 | # now we turn it into a member function | |
1862 | point.__str__ = point_str | |
1863 | ||
1864 | [*All] point instances created from C++ will also have this member function! | |
1865 | This technique has several advantages: | |
1866 | ||
1867 | * Cut down compile times to zero for these additional functions | |
1868 | * Reduce the memory footprint to virtually zero | |
1869 | * Minimize the need to recompile | |
1870 | * Rapid prototyping (you can move the code to C++ if required without changing the interface) | |
1871 | ||
1872 | You can even add a little syntactic sugar with the use of metaclasses. Let's | |
1873 | create a special metaclass that "injects" methods in other classes. | |
1874 | ||
1875 | # The one Boost.Python uses for all wrapped classes. | |
1876 | # You can use here any class exported by Boost instead of "point" | |
1877 | BoostPythonMetaclass = point.__class__ | |
1878 | ||
1879 | class injector(object): | |
1880 | class __metaclass__(BoostPythonMetaclass): | |
1881 | def __init__(self, name, bases, dict): | |
1882 | for b in bases: | |
1883 | if type(b) not in (self, type): | |
1884 | for k,v in dict.items(): | |
1885 | setattr(b,k,v) | |
1886 | return type.__init__(self, name, bases, dict) | |
1887 | ||
1888 | # inject some methods in the point foo | |
1889 | class more_point(injector, point): | |
1890 | def __repr__(self): | |
1891 | return 'Point(x=%s, y=%s)' % (self.x, self.y) | |
1892 | def foo(self): | |
1893 | print 'foo!' | |
1894 | ||
1895 | Now let's see how it got: | |
1896 | ||
1897 | >>> print point() | |
1898 | Point(x=10, y=10) | |
1899 | >>> point().foo() | |
1900 | foo! | |
1901 | ||
1902 | Another useful idea is to replace constructors with factory functions: | |
1903 | ||
1904 | _point = point | |
1905 | ||
1906 | def point(x=0, y=0): | |
1907 | return _point(x, y) | |
1908 | ||
1909 | In this simple case there is not much gained, but for constructurs with | |
1910 | many overloads and/or arguments this is often a great simplification, again | |
1911 | with virtually zero memory footprint and zero compile-time overhead for | |
1912 | the keyword support. | |
1913 | ||
1914 | [endsect] | |
1915 | [section Reducing Compiling Time] | |
1916 | ||
1917 | If you have ever exported a lot of classes, you know that it takes quite a good | |
1918 | time to compile the Boost.Python wrappers. Plus the memory consumption can | |
1919 | easily become too high. If this is causing you problems, you can split the | |
1920 | class_ definitions in multiple files: | |
1921 | ||
1922 | [c++] | |
1923 | ||
1924 | /* file point.cpp */ | |
1925 | #include <point.h> | |
1926 | #include <boost/python.hpp> | |
1927 | ||
1928 | void export_point() | |
1929 | { | |
1930 | class_<point>("point")...; | |
1931 | } | |
1932 | ||
1933 | /* file triangle.cpp */ | |
1934 | #include <triangle.h> | |
1935 | #include <boost/python.hpp> | |
1936 | ||
1937 | void export_triangle() | |
1938 | { | |
1939 | class_<triangle>("triangle")...; | |
1940 | } | |
1941 | ||
1942 | Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE] | |
1943 | macro, and call the various export functions inside it. | |
1944 | ||
1945 | void export_point(); | |
1946 | void export_triangle(); | |
1947 | ||
1948 | BOOST_PYTHON_MODULE(_geom) | |
1949 | { | |
1950 | export_point(); | |
1951 | export_triangle(); | |
1952 | } | |
1953 | ||
1954 | Compiling and linking together all this files produces the same result as the | |
1955 | usual approach: | |
1956 | ||
1957 | #include <boost/python.hpp> | |
1958 | #include <point.h> | |
1959 | #include <triangle.h> | |
1960 | ||
1961 | BOOST_PYTHON_MODULE(_geom) | |
1962 | { | |
1963 | class_<point>("point")...; | |
1964 | class_<triangle>("triangle")...; | |
1965 | } | |
1966 | ||
1967 | but the memory is kept under control. | |
1968 | ||
1969 | This method is recommended too if you are developing the C++ library and | |
1970 | exporting it to Python at the same time: changes in a class will only demand | |
1971 | the compilation of a single cpp, instead of the entire wrapper code. | |
1972 | ||
1973 | [note This method is useful too if you are getting the error message | |
1974 | ['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling | |
1975 | a large source file, as explained in the [@../faq/fatal_error_c1204_compiler_limit.html FAQ].] | |
1976 | ||
1977 | [endsect] | |
1978 | [endsect] [/ General Techniques] | |
1979 |