The yield keyword is used to define the generator (Generator), and its specific function is to return a value from the function when return is used, the difference is that after yield is returned, the function can be executed from the place where the last yield returned. That is, yield returns a function, gives the caller a return value, and then "teleport" back, allowing the function to continue running until the yield statement is startled to return a new value.
When yield is returned, the caller actually gets an iterator object, and the value of the iterator is the return value, and the next () method that invokes the iterator causes the function to resume the yield statement's execution environment until the next yield is encountered, and if yield is not met, An exception is thrown to indicate the end of the iteration.
See an example:
>>> def Test_yield ():
... yield 1
... yield 2
... yield (up to)
...
>>> a = Test_yield ()
>>> A.next ()
1
>>> A.next ()
2
>>> A.next ()
(1, 2)
>>> A.next ()
Traceback (most recent):
File "<stdin>", line 1, in?
Stopiteration
1. Functions that contain yield
If you see a function that contains yield, which means that the function is already a generator, its execution will be a lot different from other normal functions. For example, the following simple function:
- def h ():
- print ' to be brave '
- Yield 5
- H ()
As you can see, after calling H (), the print statement is not executed! This is yield, so how do you get the print statement to execute? This is the question to be discussed later, through the discussion and study later, we will understand how yield works.
2. Yield is an expression
Python2.5 Previously, Python yield was a statement, but now in 2.5, yield is an expression, such as:
- m = Yield 5
The return value of the expression (yield 5) is assigned to M, so that M = 5 is wrong. So how do you get the return value (yield 5)? You need to use the Send (msg) method that is described later.
3. See the principle through the next () statement
Now, let's reveal how yield works. We know that the H () above is called and is not executed because it has a yield expression, so we let it execute through the next () statement. The next () Statement resumes generator execution, and until the next yield expression. Like what:
- def h ():
- print ' Wen Chuan '
- Yield 5
- print ' fighting! '
- c = h ()
- C.next () C.next ()
When called, H () starts execution until yield 5 is encountered, so the output is:
- Wen Chuan
When we call C.next () again, we continue execution until we find the next yield expression. Because there is no python yield at the back, the exception is thrown:
- Wen Chuan
- fighting!
- Traceback (most recent):
- File "/home/evergreen/codes/yidld.py", line one, in <module>
- C.next ()
- Stopiteration
4. Send (MSG) and Next ()
Once we see how next () is going to make the function that contains yield, let's look at another very important function, send (msg). In fact, next () and send () function in a certain sense is similar, the difference is that send () can pass the value of the yield expression in, and next () cannot pass a specific value, can only pass the none in. Therefore, we can be seen as C.next () and C.send (None) are the same. Take a look at this example:
- def h ():
- print ' Wen Chuan ',
- m = Yield 5 # fighting!
- Print m
- D = Yield 12
- print ' We are together! '
- c = h ()
- C.next () #相当于c. Send (None)
- C.send (' fighting! ') # (yield 5) expression is given the ' fighting! ' The result of the output is:
- Wen Chuan fighting!
It should be recalled that the first call, using the next () statement or send (None), cannot use Send to send a value other than None, otherwise it will be wrong, because there is no Python yield statement to receive this value.
5. The return value of Send (msg) and Next ()
Send (MSG) and Next () have return values, their return values are special and return the parameters of the next yield expression. Yield 5, for example, returns 5. Do you understand something here? In the first example of this article, traversing Generator with the for I in Alist actually calls alist each time. Next (), and every time alist. The return value of Next () is exactly the yield parameter, which is what we begin to think is being pressed in. Let's continue with the above example:
- def h ():
- print ' Wen Chuan ',
- m = Yield 5 # fighting!
- Print m
- D = Yield 12
- print ' We are together! '
- c = h ()
- m = C.next () #m Gets the parameter value of yield 5 5
- D = c.send (' fighting! ') #d gets the parameter value of yield 12 12
- print ' We'll never forget the date ', M, '. ', d output result:
- Wen Chuan fighting!
- We'll never forget the date 5. 12
6. Throw () and close () interrupt Generator
Interrupt generator is a very flexible technique that can be used to terminate generator by throwing a generatorexit exception. The Close () method works the same, but inside it is called throw (generatorexit). We look at:
- def close (self):
- Try
- Self.throw (Generatorexit)
- Except (Generatorexit, stopiteration):
- Pass
- Else
- Raise RuntimeError ("generator ignored Generatorexit")
- # Other exceptions is not caught
Therefore, when we call the close () method and then call next () or send (msg), an exception is thrown:
- Traceback (most recent):
- File "/home/evergreen/codes/yidld.py", line +, in <module>
- D = c.send (' fighting! ') #d gets the parameter value of yield 12 12
- Stopiteration
Python yield usage (tornado, coroutine)