FAQ
Hi all,
after a long and unsuccessful search about extending C++ classes by
Python methods, I came up to the point where a couple of basic questions
should be answered:

1. Can we add new (Python) methods to a C object wrapper, e.g. after it has
been instantiated with a normal (C) method table ?
2. if not: can we add a new method to an already imported Python class ? If
yes, how can we do it, assuming to start from a method statement hosted by a
string ?

I understand that the latest version (2.2.1) allows for defining a class
which inherits from a C type, so that we can define some Python methods on
it, while retaining the capability of inherited C methods.
The point is that I want to add Python methods on demand to such class.
Thanks,

Renzo Tomaselli

Search Discussions

  • Alex Martelli at Jul 5, 2002 at 5:02 pm

    Renzo Tomaselli wrote:

    Hi all,
    after a long and unsuccessful search about extending C++ classes by
    Python methods, I came up to the point where a couple of basic questions
    should be answered:
    Just in case you're more comfortable with Italian, I want to point out
    that you can also post these questions in Italian on group it.comp.lang
    (start the subject with [Python]). Here you get many more responders,
    though, so a better chance. [Right now for example I'm not following
    it.comp.lang -- and not comp.lang.python either, as I _must_ get back
    to writing and editing, I'm just dipping in for old times' sake:-)].

    1. Can we add new (Python) methods to a C object wrapper, e.g. after it
    has been instantiated with a normal (C) method table ?
    What happens when you try to add attributes to a C-coded object depends
    on how that C-coded object has defined its setattro slot (or its setattr
    slot, but that's an older and less general way to do things). And
    similarly for the getattro that implicitly happens when the attribute
    is "gotten" prior to calling it.

    So, it all depends on how you code your C extension.
    2. if not: can we add a new method to an already imported Python class ?
    If yes, how can we do it, assuming to start from a method statement hosted
    by a string ?
    Given a Python class object, whether classic or new-style, setattr works
    just fine. Not sure what is "a method statement hosted by a string".

    I understand that the latest version (2.2.1) allows for defining a class
    which inherits from a C type, so that we can define some Python methods on
    it, while retaining the capability of inherited C methods.
    Yes, as long as that C-coded type IS specifically coded as to support
    being inherited from. Once again, it all depends on how you code at
    the C level.

    One way to avoid depending on how the C-level code is written is to
    use wrapping and automatic delegation in your Python class -- that
    also works in 2.1 and earlier, not quite as fast as inheritance but
    the difference may not be dramatic. For an example, see
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295
    (or, better, the expanded and clarified version in the printed
    Python Cookbook, ed. Martelli and Ascher, but that's only due out
    in 3 weeks, so, meanwhile, the original online version will do:-).


    Alex
  • Laura Creighton at Jul 5, 2002 at 7:18 pm
    <snip>
    For an example, see
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295
    (or, better, the expanded and clarified version in the printed
    Python Cookbook, ed. Martelli and Ascher, but that's only due out
    in 3 weeks, so, meanwhile, the original online version will do:-).


    Alex
    Hmmm, how much work will there be to make the on-line version
    compatible with the book? Is that the intention?

    Laura
  • Alex Martelli at Jul 5, 2002 at 8:17 pm

    On Friday 05 July 2002 21:18, Laura Creighton wrote:
    <snip>
    For an example, see
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295
    (or, better, the expanded and clarified version in the printed
    Python Cookbook, ed. Martelli and Ascher, but that's only due out
    in 3 weeks, so, meanwhile, the original online version will do:-).
    Hmmm, how much work will there be to make the on-line version
    compatible with the book? Is that the intention?
    I wouldn't mind, but it's out of the question that I can find the time
    until I'm done with the Nutshell. I don't know what are the plans of
    ActiveState -- if they have any resources allocated to fund that
    substantial effort (the site is ActiveState's, after all).


    Alex
  • Renzo Tomaselli at Jul 8, 2002 at 3:02 pm
    Alex Martelli <aleax at aleax.it> wrote in message news:<hikV8.47155$vm5.1686976 at news2.tin.it>...
    Renzo Tomaselli wrote:
    1. Can we add new (Python) methods to a C object wrapper, e.g. after it
    has been instantiated with a normal (C) method table ?
    What happens when you try to add attributes to a C-coded object depends
    on how that C-coded object has defined its setattro slot (or its setattr
    slot, but that's an older and less general way to do things). And
    similarly for the getattro that implicitly happens when the attribute
    is "gotten" prior to calling it.

    So, it all depends on how you code your C extension.
    Ok, I will investigate further about slots.
    2. if not: can we add a new method to an already imported Python class ?
    If yes, how can we do it, assuming to start from a method statement hosted
    by a string ?
    Given a Python class object, whether classic or new-style, setattr works
    just fine. Not sure what is "a method statement hosted by a string".
    I mean a function declaration in a string. In short, what I miss is a
    way to transform it into a callable object to be added to a class.
    Whether such class is just a wrapper on my C++ object or a Python
    derived class depends on issue below.
    I'm lost here between PyRun_String and PyCompile_String, which seem
    the only places where I can start from code strings to add methods on
    the fly.
    I understand that the latest version (2.2.1) allows for defining a class
    which inherits from a C type, so that we can define some Python methods on
    it, while retaining the capability of inherited C methods.
    Yes, as long as that C-coded type IS specifically coded as to support
    being inherited from. Once again, it all depends on how you code at
    the C level.
    Could you please explain this topic a little further ? How do we
    enable a C type to be inherited from by a Python class ?
    One way to avoid depending on how the C-level code is written is to
    use wrapping and automatic delegation in your Python class -- that
    also works in 2.1 and earlier, not quite as fast as inheritance but
    the difference may not be dramatic. For an example, see
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52295
    (or, better, the expanded and clarified version in the printed
    Python Cookbook, ed. Martelli and Ascher, but that's only due out
    in 3 weeks, so, meanwhile, the original online version will do:-).


    Alex
    Ok, got it. The overall issue is dealt with in the opposite way I'm
    interested in: almost all involved discussions on this list handle
    about estending Python by C/C++ while I need to extend C++ by Python.
    And possibly by adding just functions (methods), no extra class stuff
    or modules.
    Thanks for any suggestion,

    Renzo Tomaselli
    ---------------------------------------------------------------------------
    TecnoTP s.n.c. Special Information System Design
    Maso Pelauchi I38050 Ronchi Valsugana, Trento TN ITALY
    e-mail: renzo.tomaselli at tecnotp.it
    ---------------------------------------------------------------------------
  • Alex Martelli at Jul 8, 2002 at 9:41 pm
    Renzo Tomaselli wrote:
    ...
    I mean a function declaration in a string. In short, what I miss is a
    way to transform it into a callable object to be added to a class.
    Whether such class is just a wrapper on my C++ object or a Python
    derived class depends on issue below.
    I'm lost here between PyRun_String and PyCompile_String, which seem
    the only places where I can start from code strings to add methods on
    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).

    With PyRun_String, passing an appropriate, initially empty dict as the
    locals argument, you can execute a statement held in a string such as
    "def somename(self, whatever): return whatever", and find in said locals
    dict under key "somename" the resulting function object.

    However, you can't add attributes to a normally-coded C (or C++)
    type -- that's another issue yet.

    Yes, as long as that C-coded type IS specifically coded as to support
    being inherited from. Once again, it all depends on how you code at
    the C level.
    Could you please explain this topic a little further ? How do we
    enable a C type to be inherited from by a Python class ?
    You need a few things, starting with Py_TPFLAGS_BASETYPE among
    the flags, but not ending there -- allocation / newing / initialization are
    the key part. For perspective, I would suggest you study subclassable
    built-in objects, such as Objects/tupleobject.c -- tuple_new and
    tuple_subtype_new are the key spots. Then, examine the alternative
    strategy in Objects/listobject.c -- since list objects are mutable, they
    need no special alloc or new, but can handle all needs in list_init and
    the functions it, in turn, calls. Objects/dictobject.c shows yet another
    strategy, and Objects/fileobject.c a pretty similar one. Offhand, I
    suspect listobject's strategy would be sufficient for your purposes, but,
    if not, the one used by dicts and file objects will most likely be.

    One way to avoid depending on how the C-level code is written is to
    use wrapping and automatic delegation in your Python class -- that
    ...
    Ok, got it. The overall issue is dealt with in the opposite way I'm
    interested in: almost all involved discussions on this list handle
    about estending Python by C/C++ while I need to extend C++ by Python.
    You're not going to be able to add to C++ classes methods on the
    fly in ways that let other C++ code call the new methods, anyway.

    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...?
    And possibly by adding just functions (methods), no extra class stuff
    or modules.
    Oh, we can do that, too -- at ten times the effort, and without any
    benefits whatsoever, but, hey, one thing I learned as a freelance is
    that, when the customer insists after you've explained that, it's best
    to accept the money the customer is so insistent to push into your
    hands (I charge by the hour, of course). This way you get the extra
    of saying "see, I had told you that" when the problems do develop:-)
    Thanks for any suggestion,
    Let's see, I'm going to spend a week's vacation in Trentino anyway,
    so, if you need further help implementing things your way rather than
    in the easy way, I'm willing to charge you just my hourly rate -- no
    extra for the trip to/from Bologna. Can't get much fairer than that...

    If you want a serious suggestion, though, it's to re-think the idea that
    you *need* to have the extensible object itself be the one that is
    implemented in C++, rather than a thin Python wrapper around it. It
    CAN be done, but, what benefits do you propose to obtain from such
    a contrarian approach...? Will they repay substantial additional effort...?

    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. I'm not privvy to the details of the new release,
    whose webpages claim to have been revised on Nov 5, 2002 (!),
    but in the previous v1 the Boost guys had basically implemented a
    custom metaclass (...and by the hard and complicated rules that
    were needed in older Pythons, no less...) that should make it easier
    to implement your exact specs, once one understands it well enough
    to know what to tweak. Boost Python can surely be recommended
    for the dyed-in-the-wool, hard and pure C++ hacker. I used to
    qualify (and I'm still a C++ MVP for Brainbench), but I've since seen
    the light and left an otherwise-excellent but deeply C++-centered
    job in order to do Python full time instead. Of course, just like one
    who used to smoke heavily then quit, this may leave me, at times,
    slightly intolerant of typical C++ complications ... :-).


    Alex
  • Renzo Tomaselli at Jul 9, 2002 at 11:21 am
    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
  • Alex Martelli at Jul 9, 2002 at 12:44 pm

    Renzo Tomaselli wrote:

    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.
    It keeps looking to me as if you're making a lot of implicit assumptions,
    and that many of them are wrong. What makes you believe, for example,
    that just exec'ing "def foo(self): pass" does NOT leave you "a compiled
    form" of function foo (in the locals dictionary used for executing)?
    You can marshal such objects to bytestrings, too, for storing as BLOBs
    or whatever.
    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.
    But it's not. exec that with a locals dictionary, and in the dictionary
    at key 'foo' you find exactly a Python callable object (a function
    object, to be precise). What IS "so hard" about this? def is an
    executable statement, used to create function objects, so, if you
    start with a def statement and want a function object, you, of course,
    execute the statement. What COULD possibly be easier or mote natural?

    Maybe you have some unspoken assumption that "compiling" is what
    gives you an executable object. But it's not necessarily so, in
    Python. In Python, you get an executable object (a function)
    from executing a def statement. Compiling (using the compile
    built-in) gives you a *code* object, which is "executable" in
    a sense but is not directly *callable* -- and you do need a
    *callable* object for your purposes (a function is callable).

    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).
    My point exactly.
    So let's see this "easy" way in more details. Sure.
    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
    OK, here's a specific example -- inhe.c exposing an inheritable type
    with no other functionality (simplified mostly to remove a zillion
    zeros from the type struct, you can reconstruct it from comments):

    #include "Python.h"

    typedef struct {
    PyObject_HEAD
    } inhe;

    static void
    inhe_dealloc(PyObject *op)
    {
    op->ob_type->tp_free(op);
    }

    static PyTypeObject inhe_t = {
    PyObject_HEAD_INIT(0)
    0,
    "inhe",
    sizeof(inhe),
    0,
    inhe_dealloc,
    ...
    0, /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
    "inheritable type",
    0, /* tp_traverse */
    ...
    0, /* tp_init */
    PyType_GenericAlloc, /* tp_alloc */
    PyType_GenericNew, /* tp_new */
    _PyObject_Del, /* tp_free */
    };

    static PyMethodDef no_methods[] = { {0} };

    void
    initinhe(void)
    {
    PyObject* self;
    inhe_t.ob_type = &PyType_Type;
    self = Py_InitModule("inhe", no_methods);
    PyObject_SetAttrString(self, "inhe", (PyObject*)&inhe_t);
    }

    Save this as inhe.c, make a setup.py in the same directory with:

    from distutils.core import setup, Extension

    setup(name = "inhe",
    version = "1.0",
    description = "inheritable type",
    maintainer = "Alex Martelli",
    maintainer_email = "aleaxit at yahoo.com",

    ext_modules = [ Extension('inhe', sources=['inhe.c']) ]
    )

    cd to that directory and do "python setup.py install" and
    you'll be able to try out some Python code using it, e.g.

    import inhe

    class gop(inhe.inhe): pass

    g = gop()
    g.pop#
    print g.pop
    del g
    print 'OK'

    class like:

    #P1: wrapping
    import myExt

    class foo(myFoo): # one class per object to wrap
    pass
    Definitely *NOT* per-object, but rather per CLASS (or type) to wrap.
    And if myFoo is a class exposed from myExt, you need to use myExt.myFoo
    as the base class.
    myExt.hook(foo())
    Not quite sure what this hook function is, but presumably it's
    something your module myExt uses to keep track of subclasses of
    the classes it exposes, which seems OK (you could do it slightly
    differently, by tweaking the metaclass for example, but as you
    don't intend to let endusers freely subclass your extension's
    classes the simpler mechanism appears to be the better one here).

    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.
    "From C++" is unclear to me, unless it's via PyRun_* or the like.

    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.
    Or in other Python-oriented ways, yes.
    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).
    And I still don't see why you "still prefer" a more complex solution
    to a simpler one. Except, perhaps, due to some unspoken (and wrong)
    assumptions, as I hypothesized above.

    There's nothing particularly mysterious about "dealing with callables":
    the only difference between a callable and any other Python object
    is that the former has a non-null entry in tp_call, which changes
    just about nothing else except allowing Python code to call it!
    (Classic-class instances typically have nonnull entries everywhere
    and need more complicated tests to check if they're callable and
    so on -- but you don't need to worry about classic classes here).
    Missing precompilation is another missing feature of this solution.
    Just because you choose to "merge together in a string", above,
    several steps that you might perfectly well keep separate. As I
    have by now repeated a few too many times, but don't seem to be
    getting through to you: if you exec JUST the def statement, and
    supply an initially empty local dict, then you can fish out of
    that dict the function object, and do various things with it --
    including marshaling it into a bytestring to be saved and restored
    at will, as well as setting it as an attribute of one or more
    classes. Nothing stops you from building the classes with
    PyClass_New, if for some reason you think that's preferable to
    simpler Python ways (it's not, but it's not terribly worse either,
    so, suit yourself) --

    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.
    _Everything_ you'll find "deals primarily with extending", because
    that's where all the interesting / difficult / challenging stuff IS.

    Embedding is very simple once you have totally mastered extending.

    Your problems might stem from trying to skip the "totally mastered"
    step. Once you have a complete working solution in Python with
    extensions, moving some or all of the solution back into C or C++
    code is invariably rather trivial, although verbose/boring if indeed
    it's worth doing at all. But starting with a Python-coded prototype is
    most often the best idea -- Python+extensions, in this case.
    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.
    If you have tiny C++ programs to start with, the idea of adding 10KB
    or code, of more, can indeed be unsettling -- I tend not to think
    of that because the C++ programs I dealt with tended to be megabytes
    rather than kilobytes, so a few tens of KB more or less didn't matter.

    Further, Boost Python is hardly a SIMPLE piece of code -- the C API
    are much simpler (although fussier and messier to deal with, as is
    often the case for C-coded versus C++-coded functionality). So, if
    you don't need it (because you need to expose to Python only a very
    few, simple classes, and would take no advantage of the many extras
    that Boost Python embodies, such as setters/getters, ability to
    override virtual functions from Python in such a way that the
    override will also be seen by C++ callers, etc, etc), the simpler
    solution, based on Python's C API, can surely be preferable.

    The puzzle is that you seem persistently unsatisfied with said
    "simpler solution", and I _still_ can't quite grasp WHY.


    Alex
  • Renzo Tomaselli at Jul 10, 2002 at 10:26 am
    Alex Martelli <aleax at aleax.it> wrote in message news:<3VAW8.59624$vm5.2174084 at news2.tin.it>...
    It keeps looking to me as if you're making a lot of implicit assumptions,
    and that many of them are wrong. What makes you believe, for example,
    that just exec'ing "def foo(self): pass" does NOT leave you "a compiled
    form" of function foo (in the locals dictionary used for executing)?
    You can marshal such objects to bytestrings, too, for storing as BLOBs
    or whatever.
    Yuup! this was the big missing point. Indeed I need to marshal all
    functions (user-defined methods, actually) down to my OODBMS (and the
    entire Python library too). Trapping/restricting import and all that
    stuff I know about.
    Now I know how to move from string methods to function objects, which
    can be attached as methods to classes derived from my C++ wrappers.
    I think I got a fairly complete picture now, so I will start to
    simulate something and see what happens.
    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.
    But it's not. exec that with a locals dictionary, and in the dictionary
    at key 'foo' you find exactly a Python callable object (a function
    object, to be precise). What IS "so hard" about this? def is an
    executable statement, used to create function objects, so, if you
    start with a def statement and want a function object, you, of course,
    execute the statement. What COULD possibly be easier or mote natural?
    True but not obvious. I spent days in searching through this list on
    Google (and on C++ SIG as well). There are many messages about
    extending/embedding but none came to the above conclusions when the
    target is focused on methods.

    Thank you very much Alex, let me know if you plan to visit this area
    in the near future.
    Renzo Tomaselli
    ---------------------------------------------------------------------------
    TecnoTP s.n.c. Special Information System Design
    Maso Pelauchi I38050 Ronchi Valsugana, Trento TN ITALY
    Tel. +39 0461 773164 Fax. +39 0461 771514
    e-mail: renzo.tomaselli at tecnotp.it
    ---------------------------------------------------------------------------
  • Alex Martelli at Jul 10, 2002 at 2:17 pm
    Renzo Tomaselli wrote:
    ...
    You can marshal such objects to bytestrings, too, for storing as BLOBs
    or whatever.
    Yuup! this was the big missing point. Indeed I need to marshal all
    functions (user-defined methods, actually) down to my OODBMS (and the
    Slightly imprecise of me -- you can't marshal.dumps the function
    object f itself; rather you marshal its f.func_code (then rebuild
    a function object from the unmarshaled code with new.function):
    def f(): print 'ciao!'
    ...
    maco = marshal.dumps(f.func_code)
    # save and later reload bytestring maco at will
    newf = new.function(marshal.loads(maco), {})
    newf()
    ciao!
    >>>

    Globals and argument defaults too if you need them, of course.

    The function becomes a method later (via new.instancemethod or
    otherwise).

    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.
    But it's not. exec that with a locals dictionary, and in the dictionary
    at key 'foo' you find exactly a Python callable object (a function
    object, to be precise). What IS "so hard" about this? def is an
    executable statement, used to create function objects, so, if you
    start with a def statement and want a function object, you, of course,
    execute the statement. What COULD possibly be easier or mote natural?
    True but not obvious. I spent days in searching through this list on
    Google (and on C++ SIG as well). There are many messages about
    extending/embedding but none came to the above conclusions when the
    target is focused on methods.
    Right. The "focus on methods" may be the misleading part, given that
    the Python-coded function becomes a method object separately from all
    the rest of the operation -- just a hypothesis on why things may not
    have been said in this particular context earlier!

    Thank you very much Alex, let me know if you plan to visit this area
    in the near future.
    I'm vacationing in Trentino-Alto Adige around Ferragosto, but near
    the Lago di Carezza, not in Valsugana this year!-)


    Alex
  • Achim Domma at Jul 5, 2002 at 5:51 pm
    "Renzo Tomaselli" <renzo.tomaselli at tecnotp.it> wrote in message
    news:ag4gib$m5t$1 at news.flashnet.it...
    after a long and unsuccessful search about extending C++ classes by
    Python methods, I came up to the point where a couple of basic questions
    should be answered:
    Have looked at boost.python (www.boost.org) ?

    Achim
  • David LeBlanc at Jul 5, 2002 at 6:47 pm
    Have you looked at Boost? www.boost.org

    David LeBlanc
    Seattle, WA USA
    -----Original Message-----
    From: python-list-admin at python.org
    [mailto:python-list-admin at python.org]On Behalf Of Renzo Tomaselli
    Sent: Friday, July 05, 2002 9:14
    To: python-list at python.org
    Subject: adding methods on the fly


    Hi all,
    after a long and unsuccessful search about extending C++ classes by
    Python methods, I came up to the point where a couple of basic questions
    should be answered:

    1. Can we add new (Python) methods to a C object wrapper, e.g.
    after it has
    been instantiated with a normal (C) method table ?
    2. if not: can we add a new method to an already imported Python
    class ? If
    yes, how can we do it, assuming to start from a method statement
    hosted by a
    string ?

    I understand that the latest version (2.2.1) allows for defining a class
    which inherits from a C type, so that we can define some Python methods on
    it, while retaining the capability of inherited C methods.
    The point is that I want to add Python methods on demand to such class.
    Thanks,

    Renzo Tomaselli


    --
    http://mail.python.org/mailman/listinfo/python-list

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJul 5, '02 at 4:14p
activeJul 10, '02 at 2:17p
posts12
users5
websitepython.org

People

Translate

site design / logo © 2022 Grokbase