how to dynamically create class methods ?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Tue Mar 25 16:54:08 EDT 2008


En Tue, 25 Mar 2008 17:17:16 -0300, j vickroy <jim.vickroy at noaa.gov>  
escribió:

> Arnaud Delobelle wrote:
>> On Mar 25, 6:13 pm, j vickroy <jim.vick... at noaa.gov> wrote:
>>> Hello,
>>>
>>> Here is some pseudo-code that hopefully illustrates what I want to do:
>>>
>>> records = list(...)
>>> for record in records:
>>>     new_fcn = define_a function_for(record)
>>>     instance = my_new_class_instance()
>>>     setattr(instance, 'myfcn', new_fcn)
>>>     instance.execute() # instance.execute() calls instance.myfcn(*args)
>>>
>>> I have looked at some of the functions in the *new* module and
>>> new.code(...), new.function(...), and new.instancemethod(...) appear to
>>> do what I want, but I do not know how to use new.code() and
>>> new.function() -- specifically what its *global* parameter should be.
>>
>> The best way to understand how new.function and new.code work is to
>> look at the Python source.  (Objects/funcobject.c and Objects/
>> codeobject.c, actual objects are defined in and Include/funcobject.h
>> Include/code.h).
>>
>> However, to create a function dynamically in Python it is often no
>> more trouble than a def statement:
>
> As per your suggestion, I tried looking at include/code.h and
> include/funcobject.h (my MS Windows distribution does not appear to
> contain .c files).  However, since I'm not a C programmer, I did not
> find the .h files all that helpful.

It's not really necesary to look at the source - just define the desired  
function in Python.

> What I failed to make clear in my original posting is that the functions
> must be created dynamically using information in a *record* as the code
> iterates over all *records*.  So, I can not pre-define the functions and
> then simply select the desired one at run-time.

It doesn't matter *how* you define the function. It may use the record  
argument too. See this silly and contrived example:

def define_a function_for(record):
   if hasattr(record, 'foo'):
     def function_float(self, arg1, arg2):
       return arg1*float(record.foo) + arg2
     def function_str(self, arg1, arg2):
       return arg1+arg2+len(record.foo)
     if isinstance(record.foo, str):
       return function_str
     else:
       return function_float
   elif hasattr(record, 'bar') and isinstance(record.bar,basestring):
     def function(self, arg1, arg2):
       return self.other(record.bar.index(arg1)) - record.bar.index(arg2)
     return function
   else:
     def function(self, *args):
       return 0
     return function

Plug this into your "framework" above and it should work. You don't have  
to use new.*

-- 
Gabriel Genellina




More information about the Python-list mailing list