Home >Backend Development >Python Tutorial >Why Do Nested Python Functions Access Variables at Execution Time, Not Definition Time?

Why Do Nested Python Functions Access Variables at Execution Time, Not Definition Time?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-24 13:27:30893browse

Why Do Nested Python Functions Access Variables at Execution Time, Not Definition Time?

Nested Functions and Local Variable Access

In Python, nested functions can access local variables from their enclosing scope. However, the timing of this access can be counterintuitive.

Consider the following code snippet:

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()

Instead of getting the expected output where Mary pets each animal, the output shows "Mary pets the cat" for all three animals. This behavior arises because the nested function pet_function looks up the local variable cage at the time of execution, not at the time of definition.

When the function get_petters is called, the local variable cage is assigned to each animal successively within the loop. However, by the end of the function, cage contains the last value ('cat'). When the functions returned by get_petters are called, they all access the same cage variable with the value 'cat'.

To address this issue, one can use different techniques, such as:

  • Using a partial function with a bound cage variable:

    from functools import partial
    
    def pet_function(cage):
      print "Mary pets the " + cage.animal + "."
    
    yield (animal, partial(gotimes, partial(pet_function, cage=cage)))
  • Creating a new scope for the nested function:

    def scoped_cage(cage):
      def pet_function():
          print "Mary pets the " + cage.animal + "."
      return pet_function
    
    yield (animal, partial(gotimes, scoped_cage(cage)))
  • Binding the variable as a default value for a keyword parameter:

    def pet_function(cage=cage):
      print "Mary pets the " + cage.animal + "."
    
    yield (animal, partial(gotimes, pet_function))

The above is the detailed content of Why Do Nested Python Functions Access Variables at Execution Time, Not Definition Time?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn