It's just rough to know that yield can be used to return a value plug data for a function, such as the following example:
def Addlist (alist):
for i in alist:
yield i + 1
Remove each item from the alist and plug in the i + 1. Then fetch each item by calling:
Alist = [1, 2, 3, 4]
For x in addlist (alist):
print x,
This is indeed an example of yield application, but, after reading Limodou's article " 2.5 version of yield learning experience, and after repeated experience, has a new understanding of yield.
1. Functions that contain yield
If you see a function that contains yield, this means that the function is already a generator, and its execution can be quite different from other ordinary 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 does not execute! 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, will understand the yield work principle.
2. Yield is an expression
Python2.5 before, yield was a statement, but now in 2.5, yield is an expression (Expression), such as:
The return value of the expression (yield 5) will be assigned to M, so it is assumed that M = 5 is wrong. So how do you get the return value of (yield 5)? You need to use the Send (msg) method described later.
3. Look at the principle through the next () statement
Now, let's find out how the yield works. We know that the above H () is called and not executed because it has a yield expression, so we let it execute through the next () statement. The next () Statement restores generator execution until the next yield expression. Like what:
def H ():
print 'Wen Chuan'
yield 5
print 'fighting!'
c = h ()
C.next ()
After the C.next () call, H () starts executing until it encounters yield 5, so the output results:
Wen Chuan
When we call C.next () again, the execution continues until the next yield expression is found. Because there is no yield behind it, an exception is thrown:
Wen Chuan
fighting!
Traceback (most recent call last):
File "/home/evergreen/codes/yidld.py", line one, in <module>
C.next ()
Stopiteration
4. Send (MSG) and Next ()
Having learned how next () is going to let the function that contains the yield, let's look at another very important function send (msg). In fact, next () and send () are similar in a sense, except that send () can pass the value of the yield expression, and that next () cannot pass a specific value and can only pass none. So we can be seen as
C.next () and c.send (None) function the same.
Look at this example:
--> DefH ():
Print 'Wen Chuan',
M = yield 5 # fighting!
Print m
D = yield 12
print 'We are together!'
c = h ()
C.next () # equals C.send (None)
c.send ('fighting!' #(yield 5) expression is given the ' fighting! '
The results of the output are:
Wen Chuan fighting!
You need to be reminded that the first time you call, use the next () statement or send (none), and you cannot send a value that is not None by using send, otherwise there will be an error because there is no yield statement to receive the value.
5. The return value of Send (msg) and Next ()
Send (MSG) and Next () have return values that are special and return the parameters of the next yield expression. For example, yield 5, then return 5. Do you understand something here? In the first example of this article, the generator is traversed by the for I-in alist, which is called alist every time. Next (), and each alist. The return value of Next () is exactly the yield parameter, which is what we begin to think of as being pressed in. Let's continue with the example above:
--> DefH ():
Print'Wen Chuan',
M=Yield5#fighting!
Print m
d = yield
print ' we are together! '
c = h ()
m = c.next () # m Gets the yield 5 parameter value 5
d = c.send ( ' fighting! ' ) # d Gets the parameter value of yield 12
print ' we will never forget the date ' , m, ' . ' , d
Output results:
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 throw by throwing a Generatorexit exception to terminate the generator. The close () method works the same, in fact, it is called throw (Generatorexit) internally. We look at:
def close (self):
Try:
Self.throw (Generatorexit)
except (Generatorexit, stopiteration):
Pass
Else:
raise RuntimeError ("generator ignored Generatorexit")
# Other exceptions are not caught
Therefore, when we call the close () method, and then call next () or send (msg), an exception is thrown:
Traceback (most recent call last):
File "/home/evergreen/codes/yidld.py", line , in <module>
D = c.send ('fighting!') ) #D Gets the parameter value of yield 12 12
Stopiteration
Note: The above views belong to my personal understanding, if there are deviations please criticize. Thank you!