Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function object in Python

I want to create a list of functions consisting of function objects created by a fixed base function but with different input parameters. I have written such code:

def f_base(name):
    print "I am %s" % name

f_list = []
for name in ['A', 'B']:
    f_list.append(
        lambda : f_base(name)
    )

f_list[0]()
f_list[1]()

The result is:

I am B
I am B

But I want to get:

I am A
I am B

Can someone explain why Python produces such output and what is the easiest way to get the result I need?

like image 959
Fomalhaut Avatar asked Apr 09 '26 20:04

Fomalhaut


1 Answers

All you're doing with the lambda functions now is calling f_base on the variable name in the body. The name variable is determined at the time you call those lambda functions and not at the time you create each function.

The variable name refers to 'B' after you finish looping since python keeps variables defined in for loops around after the loop is done.

This is particularly obvious if you do,

name = 'C'

after the loop and before calling the functions. Then you get,

I am C
I am C

To do what you want you need to create a closure function or, probably better, use functools.partial.

import functools

def f_base(name):
    print "I am %s" % name

f_list = []
for name in ['A', 'B']:
    f_list.append(
        functools.partial(f_base, name)
    )

f_list[0]()
f_list[1]()

Which produces,

I am A
I am B
like image 180
Jared Avatar answered Apr 12 '26 09:04

Jared



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!