1. Imagine a scene:
Imagine, I want 100 primes, and then add and sum them.
The usual idea is to find a tool (function) that can provide at least 100 primes at a time, and let it give me the 100 primes (return a list with 100 primes at a time). For 100 primes, this is obviously feasible. However, if I want an infinite number of prime numbers to accumulate, or very, very many primes to accumulate, much to almost consume the entire memory space, it is obviously inappropriate to find a tool to deliver so much data at once.
For the previous idea, we can also have a second thought, is to find a tool that can constantly produce prime numbers, this tool does not deliver 100 prime numbers at a time, only when I ask for data and it gives the next prime number (remember, this tool is memory, it knows what I have taken before, And give me the primes I need right now. In other words, it was delivered to me after a prime number, its state was preserved, it was just suspended and not destroyed), a bit like a hen lays eggs, a pat on the next egg, and then to the production. Imagine, if you have this tool, even if it provides an infinite number of primes is completely feasible, because it provides only one prime each time, there is no memory exhaustion problem. So, does this tool exist? Of course there is, and the name is called Generator (generator).
2, Generator (Generator) Principle Introduction:
There is a keyword yield in python (yield has the meaning of production). When you use yield in a function, your function changes, and it becomes the generator (generator). When you call this function, it does not return a value, but instead returns a generator object. A generator is created, and a function is added with a keyword. It's simple, but we're still confused because we don't know generator's workflow. Let's follow it with a few simple examples.
Example 1:
We define a function (Def test ()) and use the keyword yield (yield is the meaning of production, then ' Hello ' is the value it is about to produce), so a generator is generated (call test () and return a generator Object test). We assign this generator to the variable H. Now we use next () to start the generator (note: python2.x can write H.next ()) and produce a value of ' hello '.
Example 2: Example 1, what if we continue to use next () and start generator again?
The result has been an stopiterator (terminating iterator) exception. Why is this so, why not produce ' hello ', and do not start generator again from the first line of the function (test ())? Obviously yes, otherwise it will really output ' hello '. Where is the entry point for the function when you start generator the second time? Don't worry, we'll look at the following example.
Example 3:
I added a yield on the original test (), the first time to start generator output ' Hello ', and the second to start generator output ' world '. Why is this so, why the first boot generator no output ' world '? This involves the working principle of generator.
When we use next () to start generator for the first time, the entry point of the function is in the first line, that is, the function executes from the first line of test (). When executed to the keyword yield, return ' hello ', and give control to the caller, you will keep the current state (including variable values, function execution state, etc.), ready to be called again (remember ' Memory ', yes, generator retains the memory, and all the data is destroyed after the normal function is called, and no memory is persisted. When generator is started for the second time, the entry point of the function becomes >>yield ' world ', and after executing the statement, Generator continues to transfer control and holds the current state pending.
Return to the question of Example 2, why do you produce stopiterator? According to the principle of generator, the second start of generator, the function entry point in the yield ' hello ' next line, and its line of nothing, it will naturally return an exception. Does that mean I'm in the yield ' hello ' after the addition of a statement will not be abnormal, and can execute the statement? In Example 3 we added a yield statement, the result is very satisfactory. Now let's add a print statement and look at the situation.
Example 4:
The anomaly happened again! The print statement was not executed the second time generator was started. Why is that? It turns out that generator every start-up execution to find the keyword yield, when it can not find the next yield when it will say: "Stopiterator". This is why example 3 can be executed smoothly, example 4 will occur exception.
Example 5: With the previous example, you probably already know how generator works, and it's much more practice to be proficient. But it's just a matter of knowing the foundation of generator. In the first few examples, yield is a statement, in fact, it can also be a formula, this time we need to use H.send (msg). Let's look at the examples and explain them in more detail.
I added an assignment operator (' = ') to the function. The second time I start generator, I use Send (msg) to send messages, MSG is the message content, send () can start generator like next (), and it sends the MSG as its parameter to the variable a behind yield. Remember, if you do not assign a value to a via Send (msg), A=none. Do you still want to know that if there are multiple variables like a (var = yield), who will send the message sent by Send (msg)? Let's look at the following example.
Example 6:
Obviously, send (' he ') sends the message to B because B is closest to the next yield? You can try it yourself. Did you find out that it seems that we have written so many functions, but have not seen return. How does return in generator, or what is the relationship between return and our yield?
Yield in generator is equivalent to return of a normal function, but not exactly the same. The similarity is that when a function encounters a return/yield during execution, it transfers control, and the difference is that all state of the function is destroyed after the return handover, and yield suspends the function temporarily.
----------------------------------------------------------------------------------
Resources:
1. Improve your Python: Explain ' yield ' and ' generators ': http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained;
2, Python Gossip:yield generator: http://openhome.cc/Gossip/Python/YieldGenerator.html;
3, little memory Python yield and generator: http://blog.bitfoc.us/?p=502;
Python--yield and generator (generator) Brief