Local Variables in Nested Functions: A Tale of Closure and Lookup
In Python, local variables defined within nested functions can interact with the surrounding scope. To understand this interaction, let's delve into a code snippet that highlights the behavior.
from functools import partial class Cage(object): def __init__(self, animal): self.animal = animal def gotimes(do_the_petting): do_the_petting() def get_petters(): for animal in ['cow', 'dog', 'cat']: cage = Cage(animal) def pet_function(): print "Mary pets the " + cage.animal + "." yield (animal, partial(gotimes, pet_function)) funs = list(get_petters()) for name, f in funs: print name + ":", f()
Ambiguous Assignment
Running this code produces an unexpected result: "Mary pets the cat" is printed for all three animals ("cow", "dog", and "cat"). This is because the local variable cage within the nested function pet_function is captured as a closure cell.
Closure Cell
When the nested function is created, it references the local variables in the parent scope. In this case, cage is the only free variable in pet_function and is bound to a closure cell. This cell allows the function to access the outer scope's variable even after the parent function returns.
Scope Resolution
However, the problem arises when the nested function is executed. The value of cage is looked up in the surrounding scope at the time of execution, not definition. In our case, by the time the functions are called, the cage variable in the surrounding scope has already been assigned "cat" as its final value.
Workarounds
To resolve this ambiguity, we need to break the closure and prevent the nested function from accessing the surrounding scope directly. Here are a few workarounds:
By using these workarounds, we can ensure that the nested function has access to the correct local variables and avoid ambiguity in our code.
The above is the detailed content of How Do Closures Affect Local Variable Access in Nested Python Functions?. For more information, please follow other related articles on the PHP Chinese website!