Audra Jacot
Audra Jacot

Reputation: 149

A question related to function enclosure and call-by-name of Python language

Consider the following code snippet:

def part1():
    flist = []
    for i in range(10):
        def hello():
            print(f"Hello {i = }.")
        flist.append(hello)
    
    for f in flist:
        f()
part1()

Its output is:

Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.
Hello i = 9.

instead of from 0 to 9.

When modify the code like this:

def part2():
    flist = []
    for i in range(10):
        v = i
        def hello():
            print(f"Hello {v = }.")
        flist.append(hello)
        
    
    for f in flist:
        f()
part2()

The output is not change.

But when modify the code like this:

def part3():
    flist = []
    for i in range(10):
        v = i
        def hello():
            print(f"Hello {v = }.")
        flist.append(hello)
        del v
        
    
    for f in flist:
        f()
part3()

An error raised:

NameError: cannot access free variable 'v' where it is not associated with a value in enclosing scope

Why this is going to happen? Can anyone give me an explanation in low-level view?

And if I want the program to print from 0 to 9. Without change the pattern (still use nested function approach like this) What modification should I make to achieve my goal?

Upvotes: 0

Views: 21

Answers (0)

Related Questions