From 80488e2f23ed1730dbb093948c39cb2b70b15b62 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 6 Feb 2003 22:42:36 +0000 Subject: [PATCH] improved serialization and object interface sections; some sentences added to the end of the conclusion [SVN r17258] --- doc/PyConDC_2003/bpl.txt | 94 +++++++++++++++++----------- doc/PyConDC_2003/python_cpp_mix.png | Bin 0 -> 6293 bytes 2 files changed, 58 insertions(+), 36 deletions(-) create mode 100755 doc/PyConDC_2003/python_cpp_mix.png diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 62f471d0..fe0f686b 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -622,11 +622,11 @@ form that can be stored on disk or sent over a network connection. The serialized object (most often a plain string) can be retrieved and converted back to the original object. A good serialization system will automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's -virtually unlimited runtime introspection facilities for serializing -practically arbitrary user-defined objects. With a few simple and -unintrusive provisions this powerful machinery can be extended to work -for wrapped C++ objects. Here is a simple example:: +``pickle`` module is such a system. It leverages the language's strong +runtime introspection facilities for serializing practically arbitrary +user-defined objects. With a few simple and unintrusive provisions this +powerful machinery can be extended to also work for wrapped C++ objects. +Here is an example:: #include @@ -661,19 +661,33 @@ Now let's create a ``World`` object and put it to rest on disk:: >>> a_world = hello.World("howdy") >>> pickle.dump(a_world, open("my_world", "w")) -Resurrecting the ``World`` object in a different process is equally easy:: +In a potentially *different script* on a potentially *different +computer* with a potentially *different operating system*:: >>> import pickle >>> resurrected_world = pickle.load(open("my_world", "r")) >>> resurrected_world.greet() 'howdy' -Boost.Python's ``pickle_suite`` fully supports the documented -``pickle`` protocols. Of course ``cPickle`` can also be used for faster -processing. Enabling serialization of more complex C++ objects requires -a little more work than is shown in this example, but the ``object`` -interface (see next section) greatly helps in keeping the code -manageable. +Of course the ``cPickle`` module can also be used for faster +processing. + +Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol +defined in the standard Python documentation. There is a one-to-one +correspondence between the standard pickling methods (``__getinitargs__``, +``__getstate__``, ``__setstate__``) and the functions defined by the +user in the class derived from ``pickle_suite`` (``getinitargs``, +``getstate``, ``setstate``). The ``class_::def_pickle()`` member function +is used to establish the Python bindings for all user-defined functions +simultaneously. Correct signatures for these functions are enforced at +compile time. Non-sensical combinations of the three pickle functions +are also rejected at compile time. These measures are designed to +help the user in avoiding obvious errors. + +Enabling serialization of more complex C++ objects requires a little +more work than is shown in the example above. Fortunately the +``object`` interface (see next section) greatly helps in keeping the +code manageable. ------------------ Object interface @@ -693,38 +707,22 @@ Boost.Python provides a type ``object`` which is essentially a high level wrapper around ``PyObject*``. ``object`` automates reference counting as much as possible. It also provides the facilities for converting arbitrary C++ types to Python objects and vice versa. -This should significantly reduce the learning effort for prospective +This significantly reduces the learning effort for prospective extension module writers. -To illustrate, this Python code snippet:: +Creating an ``object`` from any other type is extremely simple:: - def f(x, y): - if (y == 'foo'): - x[3:7] = 'bar' - else: - x.items += y(3, x) - return x + object o(3); -Can be rewritten in C++ using Boost.Python facilities:: - - object f(object x, object y) { - if (y == "foo") - x.slice(3,7) = "bar"; - else - x.attr("items") += y(3, x); - return x; - } +``object`` has templated interactions with all other types, with +automatic to-python conversions. It happens so naturally that it's +easily overlooked. The ``extract`` class template can be used to convert Python objects to C++ types:: - object o(3); double x = extract(o); -If the C++ type cannot be extracted an appropriate exception is thrown -(``extract`` provides facilities for avoiding exceptions if this is -desired). - All registered user-defined conversions are automatically accessible through the ``object`` interface. With reference to the ``World`` class defined in previous examples:: @@ -732,6 +730,22 @@ defined in previous examples:: object as_python_object(World("howdy")); World back_as_c_plus_plus_object = extract(as_python_object); +If a C++ type cannot be converted to a Python object an appropriate +exception is thrown at runtime. Similarly, an appropriate exception is +thrown if a C++ type cannot be extracted from a Python object. +``extract`` provides facilities for avoiding exceptions if this is +desired. + +The ``object::attr()`` member function is available for accessing +and manipulating attributes of Python objects. For example:: + + object planet(World()); + planet.attr("set")("howdy"); + +``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is +converted to a Python string object which is then passed as an argument +to the ``set`` method. + The ``object`` type is accompanied by a set of derived types that mirror the Python built-in types such as ``list``, ``dict``, ``tuple``, etc. as much as possible. This enables convenient @@ -742,6 +756,8 @@ manipulation of these high-level types from C++:: d["lucky_number"] = 13; list l = d.keys(); +This almost looks and works like regular Python code, but it is pure C++. + ================= Thinking hybrid ================= @@ -765,7 +781,7 @@ clear that a pure Python implementation is too slow for numerically intensive production code. Boost.Python enables us to *think hybrid* when developing new -applications. For example, Python can be used for rapidly prototyping a +applications. Python can be used for rapidly prototyping a new application. Python's ease of use and the large pool of standard libraries give us a head start on the way to a first working system. If necessary, the working procedure can be used to discover the @@ -808,7 +824,13 @@ parsing the C++ code to be interfaced to Python, yet the interface definitions are concise and maintainable. Freed from most of the development-time penalties of crossing a language boundary, software designers can take full advantage of two rich and complimentary -language environments. +language environments. In practice it turns out that some things are +very difficult to do with pure Python/C (e.g. an efficient array +library with an intuitive interface in the compiled language) and +others are very difficult to do with pure C++ (e.g. serialization). +If one has the luxury of being able to design a software system as a +hybrid system from the ground up there are many new ways of avoiding +road blocks in one language or the other. .. I'm not ready to give up on all of this quite yet diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png new file mode 100755 index 0000000000000000000000000000000000000000..fd74cbb2247835aa8b49e91642f29713e366195b GIT binary patch literal 6293 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 Y!@fNJ(%=4NW}qnoPgg&ebxsLQ00Quv$N&HU literal 0 HcmV?d00001