comments? storing a function in an object

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Mon Jul 20 17:38:22 EDT 2009


En Mon, 20 Jul 2009 14:44:16 -0300, Francesco Bochicchio  
<bieffe62 at gmail.com> escribió:

> On Jul 20, 6:22 pm, Esmail <ebo... at hotmail.com> wrote:
>> Hello all,
>>
>> I am trying to store a function and some associated information in an
>> object so that I can later have series of functions in a list that I can
>> evaluate one at a time.
>>
>> Right now I am only storing the function itself, the number of
>> arguments it expects and its string representation. I may add other
>> information such as the acceptable range for the parameters or other
>> characteristics such as maximum or minimum.
>>
>> I wonder if anyone could comment on my implementation and offer
>> suggestions or constructive criticisms?
>>
>> The 'loading' of the functions is a bit tedious and of course care
>> has to be taken to make sure the string representation corresponds to
>> the actual function computed. It would be nice if there was an
>> automatic way to convert the function to its string representation.
>>
>> Comments or problems with the approach I have taken?
>>
>> Thanks,
>> Esmail
>>
>> --
>>
>> #!/usr/bin/env python
>>
>> #
>> # store and represent functions
>> #
>>
>> import math
>>
>> class FunctionException(Exception):
>>      """ custom exception """
>>      def __init__(self, value):
>>          self.parameter = value
>>
>>      def __str__(self):
>>          return repr(self.parameter)
>>
>> class Function(object):
>>      """ class to represent a function """
>>
>>      def __init__(self, fn, fn_str, num_vars):
>>          """
>>          the function, its string representation, and the number of  
>> variables
>>          """
>>          self.fn = fn
>>          self.fn_str = fn_str
>>          self.num_vars = num_vars
>>
>>      def eval_fn(self, variables):
>>          """ size of variables should equal num_vars .. else problem """
>>          if len(variables) == self.num_vars:
>>              result = self.fn(*variables)
>>              return result
>>          else:
>>              raise FunctionException('invalid number of args provided -  
>> '+
>>                                      'received %d, expected %d'
>>                                      %(len(variables), self.num_vars))
>>
>>      def str(self):
>>          """ return string representation of function """
>>          return self.fn_str
>>
>> def funct1(x):
>>      ''' small test function '''
>>      return x * x
>>
>> def funct2(x, y):
>>      ''' small test function '''
>>      return x + y
>>
>> def funct3(x):
>>      ''' small test function '''
>>      return 1000 + (x*x + x) * math.cos(x)
>>
>> def main():
>>      """ main method """
>>      print 'in main'
>>
>>      fn1 = Function(funct1, 'x * x', 1)
>>      fn2 = Function(funct2, 'x + y', 2)
>>      fn3 = Function(funct3, '1000 + (x*x + x) * cos(x)', 1)
>>
>>      for i in range(-10, 10):
>>          try:
>>
>>              print 'f(', [i],') =',
>>              print fn3.str(), ' => ',
>>              print fn3.eval_fn([i])
>>
>>          except FunctionException, (ex):
>>              print ex.parameter
>>
>> if __name__ == '__main__':
>>      main()
>
>
> I can offer some small suggestions: it is up to you to evaluate if
> they make sense for your app:
>
> 1. use __doc__ function standard attribute for function description
> (your fn_str); this meanst that
>    you do not need fm_str in the constructor and you have to do e.g. :
>
> def funct2(x, y):
>       ''' x + y '''
>       return x + y
>
> then funct2.__doc__  becomes the string you want to associate to the
> function
>
> 2. Use __call__ instead of eval_fn : this way, the instance of your
> Function became a 'callable' and can be used
>    everywhere a function is needed. You can do:
>
>    f = Function(...)
>    f( some_args )
>
> 3. If you call a python function with wrong number of arguments, it
> already raises a TypeError exception which contains
>    - with different wording - the same information of your
> FunctionException : consider removing the check and using the
>    python error instead

If you follow the above suggestions, you'll see that your Function class  
becomes almost useless: a normal function already IS an object, so you  
don't have to wrap it inside ANOTHER object unless you need very special  
features.

-- 
Gabriel Genellina




More information about the Python-list mailing list