标签云

微信群

扫码加入我们

WeChat QR Code

如何在Python函数返回后记住它的价值?[重复]

This question already has an answer here:

Warning: extreme newbie question

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.

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.

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.

Can someone help clear this up for me?

Here's the code from the Python wiki

 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 > 1000000:
            break
        yield number   

print sum(even(under_a_million(fib())))

And here's http://pythontutor.com/visualize.html


Your confusion is understandable. Programs do work the way you think they should (sort of), except for the yield keyword. yield, as you describe, stores a gnome under the sink. While you are learning you might choose to avoid yield, or you might choose to read up on it specifically.

2018年06月19日04分41秒

You have generators here. Generators are put on ice every time they come across a yield keyword, returning control to whatever is looping over them.

2018年06月18日04分41秒

jeffknupp.com/blog/2013/02/14/…

2018年06月19日04分41秒

I have to be perfectly honest. Your extreme level of cooking analogy has me completely and utterly confused.

2018年06月19日04分41秒

You start wandering in to stateful functions with Charlie and his crepes, which is closing on object oriented territory, but for the most part, your analogy sticks. As pointed out, yield and generators complicate the analogy, because they also act in a stateful way.

2018年06月18日04分41秒