3

Say I have a function

def my_meta_function (a, b, c):
  pass

I would like define an array of functions myfunctions = [f1, f2, f3, ... f100], where the argument c is fixed to a different value for each such function, e.g. c = [1,2,3, .. 100], and the functions only take the arguments a and b. In practice, the arguments I am considering are more complictated, but I am trying to understand how to do this in the language.

  • Does this type of meta-programming have a name?
  • Are decorators appropriate for this? If not, why?
Josh
  • 11,979
  • 17
  • 60
  • 96
  • Are the functions at all based on the arguments? Do you have the function objects already? Can you please provide more detail and a usecase? – Martijn Pieters Nov 13 '13 at 16:13
  • Thanks @MartijnPieters I have updated the post. The new functions take the arguments `(a,b)`, leaving only `c` fixed. The body of the functions would be the same. – Josh Nov 13 '13 at 16:16

2 Answers2

6

Use functools.partial:

>>> from functools import partial
def func(a, b, c):
...     print a, b, c
...     
>>> funcs = [partial(func, c=i) for i in xrange(5)]
>>> funcs[0](1, 2)
1 2 0
>>> funcs[1](1, 2)
1 2 1
>>> funcs[2](1, 2)
1 2 2

Just for learning purpose you can also do this using lambda:

>>> funcs = [lambda a, b, i=i:func(a, b, c=i) for i in xrange(5)]
>>> funcs[0](1, 2)
1 2 0
>>> funcs[1](1, 2)
1 2 1

But you should not use it, why?:

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Thanks. For me to understand better how this relates to other metaprogramming features in Python. Do you know if this can be done with a decorator? – Josh Nov 13 '13 at 16:22
  • @Josh Yes you can implement this as a decorator, look at the docs of partial you'll find an example. – Ashwini Chaudhary Nov 13 '13 at 16:23
3

You could do this:

>>> def func(c):
...    def wrapped(a, b):
...        return (a+b)*c
...    return wrapped
...
>>> funcs = [func(c+1) for c in xrange(100)]
>>> funcs[0](1, 2)
3
>>> funcs[1](1, 2)
6
jazzpi
  • 1,399
  • 12
  • 18