1 year ago

#333833

test-img

Chirag Shetty

What is the correct way to define functions with a bound variable in Python?

I want to create a family of functions each with a different parameter. In trying to doing so I encountered an issue which I demonstrate below using a dummy code (in python):

Suppose I want 4 functions such that the i-th function prints i when called.

A Naive code to do this would be:

#------ Prepare the functions----
func_list =[]
for i in range(1,5):
    def dummy():
        print("Dummy no:", i)
    func_list.append(dummy)

#----- Call the functions -------    
for func in func_list:
    func()

But it results in the wrong output:

Dummy no: 4
Dummy no: 4
Dummy no: 4
Dummy no: 4

I figured the correct way is:

#------ Prepare the functions----
def return_a_func(k):
    def dummy():
        print("Dummy no:", k)
    return dummy

func_list =[]
for i in range(1,5):
    func_list.append(return_a_func(i))
    
#----- Call the functions -------  
for func in func_list:
    func()

This gives the correct output:

Dummy no: 1
Dummy no: 2
Dummy no: 3
Dummy no: 4

I vaguely understand that this has to do with closures. But I could not reason it out clearly and completely. Specifically why did the Naive approach fail? Why couldn't Python detect that 'i' must be bound to the function 'dummy'?

Edit: The following answer suggested in the comment is very useful: Creating functions in a loop

However, It would also be great to know the rationale behind having 'late binding' as a design choice. Also, when exactly does binding happen? For instance, this does not create a binding, although one would expect it to:

    i=1
    def dummy():
        p = i
        print("Dummy no:", p)
    f= dummy

    i=2
    f()
    # this print : Dummy no: 2

python

function

closures

formal-languages

0 Answers

Your Answer

Accepted video resources