adding methods on the fly

Renzo Tomaselli renzo.tomaselli at tecnotp.it
Tue Jul 9 07:21:32 EDT 2002


Alex Martelli <aleax at aleax.it> wrote in message news:<DGnW8.46007$Jj7.1292356 at news1.tin.it>...

> Py_CompileString (careful about underscore placement!-) won't let you
> easily build a function (or unbound-method) object, which is what you
> need (though you can get there eventually, but it's a long way 'round).

Fairly disappointing. Since I plan to store such used-defined methods
into a OO database, I would expect it being much more efficient to
store them in a precompiled form.
I still wonder why it's so hard (from a C/C++ perspective) to walk
from a "def foo(self): pass" string to a callable object to be added
to a class.
 
> That being a given -- i.e., given that the client-code of your
> extended objects is going to be Python, anyway -- why not take
> the easy way out, and have said extensible objects be a Python
> shell around a C++ core?  A thin Python shell, which you can add
> with a small effort by inheritance in Python 2.2, or more easily and
> portably (with a loss of performance) by automatic delegation,
> lets you extend to your heart's content.  So, why not...?

Ok, I'm not forced to fit all in C++, after all I define the features
my platform is going to offer. An extra layer in Python is acceptable,
provided I hide it from common usage (e.g. adding/invoking methods).
So let's see this "easy" way in more details.
Let's assume I created a C++ extension in module myExt, which exports
a type for each C++ class to be wrapped (and this type is defined so
that it can be inherited from). Then I would need to defined an empty
class like:

#P1: wrapping
import myExt

class foo(myFoo):   # one class per object to wrap
    pass

myExt.hook(foo())

Then from time to time someone adds a new method to class foo:

#P2: declaration
def m1(self, args):
    do_something

#P3: appending
foo.m1 = m1

#P4: execution
and run it from C++ or from Python.

Now, the entire game is C++ driven. P1, P2, P3 can be merged together
in a string(P2 is an user-defined string) and run through
PyRun_SimpleString. Now new method is attached to class foo and it can
be run through PyObject_CallMethod on the hooked class instance.
I still prefer a PyClass_New/PyMethod_New/PyInstance_New sequence from
C++, but here we are back to the point of feeding PyMethod_New with
appropriate value from pass P2 above. This is the missing link about
which I couln't find anything on the list (dealing with callables is
general is a black hole).
Missing precompilation is another missing feature of this solution.

> Another possibility is to look at Boost Python, if the schedule for their
> new release 2 (supporting Python 2.2 fully) is compatible with your
> timing constraints

Several people suggested me to look at Boost, but I feel it deals
primarily with extending, while I'm on the opposite side.
On the other hand I don't feel good to add an entire package only for
the purpose of adding new Python methods on the fly.

Renzo



More information about the Python-list mailing list