[C++-sig] Adding a method on the fly

Stefan Seefeld seefeld at sympatico.ca
Wed Apr 5 07:55:42 CEST 2006


Kelly Burkhart wrote:
> Is it possible to add a method to an object on the fly?  Something like:
> 
> // Add a method 'foo' to object
> void addMethod( object obj )
> {
>     call_method<void>(obj.ptr(),"__setattr__", "foo", "lambda x:x+x" );
> }
> 
> The "lambda..." string would have to get evaluated by Python to return 
> an appropriate object to bind to foo.  Is there any way to do something 
> like this?

Yes, the following code ought to do what you want:

using namespace boost::python;

int main(int, char **)
{

   Py_Initialize();
   try
   {
     // Retrieve the main module
     object main = import("__main__");

     // Retrieve the main module's namespace
     object global(main.attr("__dict__"));

     // Define the derived class in Python.
     object result = exec(
       "class A:                            \n"
       "    def hello(self):                \n"
       "        return 'Hello from Python!' \n"
       "def func(self, x):                  \n"
       "    return x+x                      \n",
       global, global);
     object A = global["A"];
     A.attr("method") = global["func"];
     result = exec("a = A()                 \n"
		  "print a.hello()         \n"
		  "print a.method(21)      \n",
		  global, global);
   }
   catch (error_already_set)
   {
     PyErr_Print();
   }
}

Note that the first exec defines class 'A' as well as a function 'func'
in python and stores them in 'global'. Then, from within C++, 'func'
is attached to 'A' under the name 'method'. Finally, another chunk
of python is executed, using the same namespace (making sure the
modified 'A' class is exposed), where the newly created method is run
through a new instance of 'A'.

HTH,
		Stefan




More information about the Cplusplus-sig mailing list