0

Possible Duplicate:
Local variables in Python nested functions

Here is my problem, I need to create functions dynamically in python. I have a list in parameter and I need to create a function for each element of this list.

Here is an example :

list_func = []
list_param = ['foo','bar']

for param in list_param:
    def print_func():
        print(param)

    list_func += [print_func]

for func in list_func:
    func()

with this code the second loop will just print the last parameter. Here is the output :

bar
bar

I need

foo
bar

Thanks

2
  • 6
    Read about late binding in python. Commented Nov 16, 2012 at 10:49
  • 1
    I'm not completly sure about what you tries to acclompish. But wouldn't you be better of using classes? Commented Nov 16, 2012 at 10:51

4 Answers 4

2

Use functools.partial for this.

>>> import functools
>>> def print_func(param):
...     print(param)
...     
>>> list_func = [functools.partial(print_func, x) for x in ["foo", "bar"]]
>>> list_func[0]()
foo
>>> list_func[1]()
bar

Alternatively, you can define a callable class:

class Printer(object):
    def __init__(self, param):
        self.param = param

    def __call__(self):
        print(self.param)

then list_func = [Printer(x) for x in ["foo", "bar"]]. This might be a good idea when your function get complicated.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help, I think the callable class is the cleanest solution for my issue. I can't use functool because my print_func can not have parameters.
1

You can use lambda :

In [87]: list_func = []

In [88]: list_param = ['foo','bar']

In [89]: for param in list_param:
    list_func.append(lambda i=param:i)
   ....:     


In [91]: list_func[0]()
Out[91]: 'foo'

In [92]: list_func[1]()
Out[92]: 'bar'

Comments

1

I just modified you're code slightly:

list_func = []
list_param = ['foo','bar']

def make_print_func(param):
    def print_func():
        print(param)
    return print_func

list_func += [make_print_func(param) for param in list_param]

for func in list_func:
    func()

Now there is a function make_print_func that generates the functions that you need on the fly.

Output is this:

foo
bar

1 Comment

Thank you for your reply, it is exactly what I need but the callable class from larsmans is maybe a bit cleaner.
1
list_func = []
list_param = ['foo', 'bar']

for param in list_param:
    def print_func(arg=param): #Look at this string
        print(arg)

    list_func.append(print_func)

for func in list_func:
    func()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.