How does a function in Python remember its values after it returns?
<p>Warning: extreme newbie question</p>

<p>I seem to have been thinking of functions as a recipe. In my world, the program is a recipe box and some of the recipes (functions) call for other recipes (other functions). The processor starts executing the master recipe by writing the instructions into RAM and working through them. Like, breakfast crepes. You call the breakfast crepes recipe from Julia Childs. You have to do make the crepe batter once. Then, while you still have crepe batter, you iteratively make crepes. Concurrently, there are various fruit preparations you can make.</p>

<p>Well, I apparently don't understand. I just ran the python wiki solution to Project Euler problem 2 (sum of even Fibonacci numbers less than 4 million) through pythontutor.com. And I think something occurred to me. It seems like every time you conjure a recipe, you don't just use the same processor, you get a gnome with some pots to work on that function. The pots are variables, the gnome works out his recipe, and, if the calling function was expecting return values, the gnome shows the contents of those pots to the caller. The caller may then go back, figure out some more things, and show return values to his caller.</p>

<p>So lets say Al calls Bob to make crepes. Bob makes the batter and calls Charlie to cook them. Charlie cooks a crepe, serves that crepe to Bob, Bob gives it to Al, and goes back to Charlie. Who still exists! Al is unaware that Bob has Charlie stashed in the kitchen, but even after Charlie makes that first crepe, he's still in the kitchen, knows how to make a crepe, and knows how much crepe batter he has left. Even though he already returned the first crepe.</p>

<p>Can someone help clear this up for me?</p>

<p>Here's the code from the Python wiki</p>

<pre><code> def fib():
    x,y = 0,1
    while True:
        yield x
        x,y = y, x+y

def even(seq):
    for number in seq:
        if not number % 2:
            yield number

def under_a_million(seq):
    for number in seq:
        if number &gt; 1000000:
            break
        yield number   

print sum(even(under_a_million(fib())))
</code></pre>

<p>And here's <a href="http://pythontutor.com/visualize.html" rel="nofollow">http://pythontutor.com/visualize.html</a></p>
