In python 3.3, generator has a new syntax yield from. What is the function of yield from? What is the syntax? The following article mainly introduces the relevant information of yield from syntax in Python 3 to you in detail. Friends who need it can refer to it. Let’s take a look together.
Preface
I was tinkering with Autobahn recently, and it gave an example based on asyncio. I thought about putting it on pypy3 and running it, but it... failed. . pip install asyncio
reported invalid syntax directly. At first glance, I thought there was a problem with 2to3 processing - you can't blame me. Well, many packages were written in 2 and then converted to 3 - but it turned out that asyncio Originally it only supported version 3.3+, so I looked back at the code and suddenly found the sentence yield from
; yield
I know, but yield from
is a magic horse?
PEP-380
Okay, I came up with this title through Google. yield from
’s past and present lives are all in this PEP. In short, the general idea is The original yield
statement can only return CPU control to the direct caller. When you want to reconstruct the logic with a yield statement in a generator or coroutine into another generator (original text is subgenerator) It will be very troublesome because the outside generator is responsible for message passing for the inside generator; so someone had the idea to let python encapsulate the message passing to make it transparent to programmers, so there is yield from
.
PEP-380 specifies the semantics of yield from
, or the behavior pattern that nested generators should have.
Suppose there is such a statement in function A
yield from B()
##B() returns an iterable (iterable ) object b, then A() will return a generator - according to our naming convention, the name is a - then:
- b Each value generated by iteration is passed directly to the caller of a.
- All values sent to a through the send method are passed directly to b. If the value sent is None, the
__next__()
method of b is called, Otherwise, call the send method of b. If the method call to b generates a StopIteration exception, a will continue to execute the statements following
yield from, and other exceptions will be propagated to a, causing a to execute
yield fromthrow an exception.
- If an exception other than GeneratorExit is thrown into a, the exception will be thrown directly into b. If b's throw method throws StopIteration, a will continue to execute; other exceptions will cause a to also throw an exception.
- If a GeneratorExit exception is thrown into a, or a's close method is called, and b also has a close method, b's close method will also be called. If this method of b throws an exception, it will cause a to also throw an exception. On the contrary, if b is successfully closed, a will also throw an exception, but it is a specific GeneratorExit exception.
- The evaluation result of the
yield from
expression in a is the first parameter of the StopIteration exception thrown at the end of the iteration of b.
- The
return
statement in b will actually throw a
StopIteration() exception, so in b The value of return will become the return value of the
yield fromexpression in a.
A useless example
It’s useless because you probably don’t really want to write the program like this, but... Anyway, it’s enough to illustrate the problem. . Imagine there is such a generator function:def inner(): coef = 1 total = 0 while True: try: input_val = yield total total = total + coef * input_val except SwitchSign: coef = -(coef) except BreakOut: return totalThe generator generated by this function will accumulate the value received from the send method to the local variable total , and stop iteration when receiving a BreakOut exception; as for the other SwitchSign exception, it should not be difficult to understand, so I won’t spoil it here. From the code point of view, the generator obtained by the
inner() function receives data for calculation through send, and at the same time accepts the control of external code through the throw method to execute different code branches. So clear so far.
inner(). Since I think "if the code is not broken, don't touch it", I decided to keep
inner() as it is, and then write an
outer() and put the added code in
outer(), and provides the same operation interface as
inner(). Since
inner() utilizes several features of generator,
outer() must also do these five things:
outer()
必须生成一个generator;在每一步的迭代中,
outer()
要帮助inner()
返回迭代值;在每一步的迭代中,
outer()
要帮助inner()
接收外部发送的数据;在每一步的迭代中,
outer()
要处理inner()
接收和抛出所有异常;在
outer()
被close的时候,inner()
也要被正确地close掉。
根据上面的要求,在只有yield的世界里,outer()
可能是长这样的:
def outer1(): print("Before inner(), I do this.") i_gen = inner() input_val = None ret_val = i_gen.send(input_val) while True: try: input_val = yield ret_val ret_val = i_gen.send(input_val) except StopIteration: break except Exception as err: try: ret_val = i_gen.throw(err) except StopIteration: break print("After inner(), I do that.")
WTF,这段代码比inner()
本身还要长,而且还没处理close操作。
现在我们来试试外星科技:
def outer2(): print("Before inner(), I do this.") yield from inner() print("After inner(), I do that.")
除了完全符合上面的要求外,这四行代码打印出来的时候还能省点纸。
我们可以在outer1()
和outer2()
上分别测试 数据 以及 异常 的传递,不难发现这两个generator的行为基本上是一致的。既然如此, 外星科技当然在大多数情况下是首选。
对generator和coroutine的疑问
从以前接触到Python下的coroutine就觉得它怪怪的,我能看清它们的 行为模式,但是并不明白为什么要使用这种模式,generator和 coroutine具有一样的对外接口,是generator造就了coroutine呢,还 是coroutine造就了generator?最让我百思不得其解的是,Python下 的coroutine将“消息传递”和“调度”这两种操作绑在一个yield 上——即便有了yield from
,这个状况还是没变过——我看不出这样做 的必要性。如果一开始就从语法层面将这两种语义分开,并且为 generator和coroutine分别设计一套接口,coroutine的概念大概也会 容易理解一些。
更多Python 3中的yield from语法详解相关文章请关注PHP中文网!

Is it enough to learn Python for two hours a day? It depends on your goals and learning methods. 1) Develop a clear learning plan, 2) Select appropriate learning resources and methods, 3) Practice and review and consolidate hands-on practice and review and consolidate, and you can gradually master the basic knowledge and advanced functions of Python during this period.

Key applications of Python in web development include the use of Django and Flask frameworks, API development, data analysis and visualization, machine learning and AI, and performance optimization. 1. Django and Flask framework: Django is suitable for rapid development of complex applications, and Flask is suitable for small or highly customized projects. 2. API development: Use Flask or DjangoRESTFramework to build RESTfulAPI. 3. Data analysis and visualization: Use Python to process data and display it through the web interface. 4. Machine Learning and AI: Python is used to build intelligent web applications. 5. Performance optimization: optimized through asynchronous programming, caching and code

Python is better than C in development efficiency, but C is higher in execution performance. 1. Python's concise syntax and rich libraries improve development efficiency. 2.C's compilation-type characteristics and hardware control improve execution performance. When making a choice, you need to weigh the development speed and execution efficiency based on project needs.

Python's real-world applications include data analytics, web development, artificial intelligence and automation. 1) In data analysis, Python uses Pandas and Matplotlib to process and visualize data. 2) In web development, Django and Flask frameworks simplify the creation of web applications. 3) In the field of artificial intelligence, TensorFlow and PyTorch are used to build and train models. 4) In terms of automation, Python scripts can be used for tasks such as copying files.

Python is widely used in data science, web development and automation scripting fields. 1) In data science, Python simplifies data processing and analysis through libraries such as NumPy and Pandas. 2) In web development, the Django and Flask frameworks enable developers to quickly build applications. 3) In automated scripts, Python's simplicity and standard library make it ideal.

Python's flexibility is reflected in multi-paradigm support and dynamic type systems, while ease of use comes from a simple syntax and rich standard library. 1. Flexibility: Supports object-oriented, functional and procedural programming, and dynamic type systems improve development efficiency. 2. Ease of use: The grammar is close to natural language, the standard library covers a wide range of functions, and simplifies the development process.

Python is highly favored for its simplicity and power, suitable for all needs from beginners to advanced developers. Its versatility is reflected in: 1) Easy to learn and use, simple syntax; 2) Rich libraries and frameworks, such as NumPy, Pandas, etc.; 3) Cross-platform support, which can be run on a variety of operating systems; 4) Suitable for scripting and automation tasks to improve work efficiency.

Yes, learn Python in two hours a day. 1. Develop a reasonable study plan, 2. Select the right learning resources, 3. Consolidate the knowledge learned through practice. These steps can help you master Python in a short time.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

WebStorm Mac version
Useful JavaScript development tools

Notepad++7.3.1
Easy-to-use and free code editor

Atom editor mac version download
The most popular open source editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.