Zmienne lokalne w zagnieżdżonych funkcjach

Dobra, daj mi z tym spokój, wiem, że będzie to wyglądało strasznie zawiłe, ale proszę, pomóż mi zrozumieć, co się dzieje.

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

Daje:

cow: Mary pets the cat.
dog: Mary pets the cat.
cat: Mary pets the cat.

Więc zasadniczo, dlaczego nie dostaję trzech różnych zwierząt? Nie jestcage „spakowane” do lokalnego zakresu zagnieżdżonej funkcji? Jeśli nie, w jaki sposób wywołanie funkcji zagnieżdżonej wyszukuje zmienne lokalne?

Wiem, że napotkanie takich problemów zazwyczaj oznacza, że ​​„robi to źle”, ale chciałbym zrozumieć, co się dzieje.

questionAnswers(3)

yourAnswerToTheQuestion