Deep understanding of Python yield

Source: Internet
Author: User
Tags generator

78915518

Python2 and Python3 are incompatible, and the entire environment is python3.6

A simple yield instance

Previously it was only sketchy to know what yield can be used to return value plug data for a function, such as the following example:

def addlist(alist):    for i in alist: yield i + 1

alisttake out each item and then i + 1 tuck it in. Each entry is then fetched by calling:

alist = [1, 2, 3, 4]for x in addlist(alist): print(x)

This is indeed yield an example of application, but after seeing a lot of things and experiencing it over and over again, there is a whole new understanding of yield, which is a fine piece.

Functions that contain yield

If you see that a function yield is contained, which means that the function is already one Generator , its execution will be different from other normal functions. For example, the following simple function:

def h():    print(‘study yield‘) yield 5 print(‘go on!‘)h()

As you can see, h() after the call, the print statement is not executed! This is yield . The specific content will be more and more clear later, including yield how it works.

Yield is an expression

Python 2.5 ago, yield is a statement, I did not research, because it was not used, now yield is an expression:

m = yield 5

The return value of the expression (yield 5) will be assigned to M, so it m = 5 must be wrong.

So how do you get the return value (yield 5)? Need to use send(msg) .

How yield works

yieldThe working principle of the announcement requires a matching next() function. The above h() is called after it is not executed, because it has an yield expression that next() can be resumed by Generator execution until the next yield .

def h():    print(‘study yield‘) yield 5 print(‘go on!‘)c = h()d1 = next(c) # study yieldd2 = next(c)"""study yieldgo on!Traceback (most recent call last): File "D:/idea/workspace/pythonSpace/PythonDemo/static/yield_demo.py", line 35, in <module> d2 = next(c)StopIteration"""
    • 1
    • 2
    • 3
    • 4

next()After being called, h() execution begins until it encountersyield 5

So the output is:study yield

When we call again next() , we continue to execute until we find the yield next. Because there is no later yield , the exception is thrown out:

yieldgo on!Traceback (most recent call last):  File "D:/idea/workspace/pythonSpace/PythonDemo/static/yield_demo.py", line 35, in <module> d2 = next(c)StopIteration

Send (MSG) with Next ()

next()once we know how to make yield the included function execute, let's look at another very important function send(msg) .

next()in fact, send() it's similar in some sense.

Difference

send()Values that can be passed yield

next()Can only be passed None .

So next() send(None) The function is the same.

def s():    print(‘study yield‘) m = yield 5 print(m) d = yield 16 print(‘go on!‘)c = s()s_d = next(c) # 相当于send(None)c.send(‘Fighting!‘) # (yield 5)表达式被赋予了‘Fighting!‘

The result of the output is:

yieldFighting!

Note When the generator is started (first call), use the next() statement or send(None) not to send a value that is not none directly, otherwise it will be reported TypeError because there is no yield statement to receive this value.

The return value of Send (msg) and Next ()

send(msg)and next() The return value is special, is yield the argument of the next expression (yield 5, returns 5).

Here, the first example, through for i in alist traversal Generator , is actually called every time next() , and each time next() the return value is exactly yield the parameter:

def s():    print(‘study yield‘) m = yield 5 print(m) d = yield 16 print(‘go on!‘)c = s()s_d1 = next(c) # 相当于send(None)s_d2 = c.send(‘Fighting!‘) # (yield 5)表达式被赋予了‘Fighting!‘print(‘My Birth Day:‘, s_d1, ‘.‘, s_d2)

Output Result:

yieldFighting!My Birth Day: 5 . 16

Interrupt Generator

In the above example, when there is no executable program, it throws one StopIteration , during the development process, interrupt generator is a very flexible technique

Throw

Terminates generator by throwing a generatorexit exception.

Close

The role of close and throw is the same, look at its source code, it can be found that it and raise a ball like

def throw(self, type, value=None, traceback=None):    ‘‘‘Used to raise an exception inside the generator.‘‘‘ # 用于在生成器中抛出一个异常。 passdef close(self): ‘‘‘Raises new GeneratorExit exception inside the generator to terminate the iteration.‘‘‘ # 在生成器中生成新的GeneratorExit异常来终止迭代。 pass

In fact, the last interrupt generator can be ignored, in the development process, it is unavoidable to use these, but Python3 internal has done very well, and generally do not need to do this thing manually.

Demo Address

https://github.com/seeways/PythonDemo/blob/master/static/yield_demo.py

Deep understanding of Python yield

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.