A brief analysis of the use of Python yield
You may have heard that a function with yield is called a generator in Python. What is a generator?
Let’s put aside generators first and use a common programming topic to demonstrate the concept of yield.
How to generate the Fibonacci sequence
The Fibonacci sequence is a very simple recursive sequence. Except for the first and second numbers, any number can be obtained by adding the first two numbers. . Using a computer program to output the first N numbers of the Fibonacci sequence is a very simple problem. Many beginners can easily write the following function:
List 1. Simply output the first N numbers of the Fibonacci sequence
deffab(max): n, a, b =0, 0, 1 whilen < max: printb a, b =b, a +b n =n +1
Executing fab(5), we can get the following output:
>>> fab(5)
There is no problem with the result, but experienced developers will point out that using print to print numbers directly in the fab function will cause the function to The reusability is poor because the fab function returns None and other functions cannot obtain the sequence generated by this function.
To improve the reusability of the fab function, it is best not to print out the sequence directly, but to return a List. The following is the rewritten second version of the fab function:
List 2. Output the first N numbers of the Fibonacci sequence Second version
deffab(max): n, a, b =0, 0, 1 L =[] whilen < max: L.append(b) a, b =b, a +b n =n +1 returnL
You can use the following method to print out the List returned by the fab function:
>>> forn infab(5):
... printn
...
The rewritten fab function can meet the reusability requirements by returning a List, but more experienced developers will point out that the function is running The memory occupied will increase as the parameter max increases. If you want to control the memory usage, it is best not to use List
to save intermediate results, but to iterate through iterable objects. For example, in Python2. ): pass
will not generate a List of 1000 elements, but will return the next value in each iteration, occupying very little memory space. Because xrange does not return a List, but an iterable object.
Using iterable, we can rewrite the fab function into a class that supports iterable. The following is the third version of Fab:
Listing 4. The third version
classFab(object): def__init__(self, max): self.max=max self.n, self.a, self.b =0, 0, 1 def__iter__(self): returnself defnext(self): ifself.n < self.max: r =self.b self.a, self.b =self.b, self.a +self.b self.n =self.n +1 returnr raiseStopIteration()
The Fab class continuously returns the next one in the sequence through next() Number, the memory usage is always constant:
>>> forn inFab(5):
... printn
...
However, the code of this version rewritten using class is far from the first version of fab Functions come in simple terms. If we want to keep the simplicity of the first version of the fab function while getting iterable effects, yield comes in handy:
Listing 5. The fourth version of fab using yield
deffab(max): n, a, b =0, 0, 1 whilen < max: yieldb # print b a, b =b, a +b n =n +1
The fourth version of fab and Compared with the first version, just changing print b to yield b achieves the iterable effect while maintaining simplicity.
Calling the fourth version of fab is exactly the same as the second version of fab:
>>> forn infab(5):
... printn
...
Simply put, the function of yield is to A function becomes a generator. The function with yield is no longer an ordinary function. The Python interpreter will treat it as a generator. Calling fab(5) will not execute the fab function, but return an iterable object! When the for loop is executed, each loop will execute the code inside the fab function. When it reaches yield b, the fab function returns an iteration value. In the next iteration, the code continues to execute from the next statement of yield b, and the function The local variable looks exactly the same as it did before the last interruption, so the function continues execution until yield is encountered again.
You can also manually call the next() method of fab(5) (because fab(5) is a generator object, which has a next() method), so that we can see the execution process of fab more clearly:
List 6. Execution process
>>> f =fab(5)
>>> f.next()
>>> f.next()
>>> f.next()
> >> f.next()
>>> f.next()
>>> f.next()
Traceback (most recent call last):
File"", line 1, in StopIteration
When the function execution ends, the generator automatically throws a StopIteration exception, indicating that the iteration is completed. In the for loop, there is no need to handle the StopIteration exception, and the loop will end normally.
We can draw the following conclusion:
A function with yield is a generator. It is different from an ordinary function. Generating a generator looks like a function call, but will not execute any function code until next( is called on it. ) (next() will be automatically called in the for loop) before execution starts. Although the execution flow is still executed according to the flow of the function, every time a yield statement is executed, it will be interrupted and an iteration value will be returned. The next execution will continue from the next statement of yield. It looks like a function is interrupted several times by yield during normal execution, and each interruption returns the current iteration value through yield.
yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。
如何判断一个函数是否是一个特殊的 generator 函数?可以利用 isgeneratorfunction 判断:
清单 7. 使用 isgeneratorfunction 判断
>>> frominspect importisgeneratorfunction
>>> isgeneratorfunction(fab)
True
要注意区分 fab 和 fab(5),fab 是一个 generator function,而 fab(5) 是调用 fab 返回的一个 generator,好比类的定义和类的实例的区别:
清单 8. 类的定义和类的实例
>>> importtypes
>>> isinstance(fab, types.GeneratorType)
False
>>> isinstance(fab(5), types.GeneratorType)
True
fab 是无法迭代的,而 fab(5) 是可迭代的:
>>> fromcollections importIterable
>>> isinstance(fab, Iterable)
False
>>> isinstance(fab(5), Iterable)
True
每次调用 fab 函数都会生成一个新的 generator 实例,各实例互不影响:
>>> f1 =fab(3)
>>> f2 =fab(5)
>>> print'f1:', f1.next()
f1: 1
>>> print'f2:', f2.next()
f2: 1
>>> print'f1:', f1.next()
f1: 1
>>> print'f2:', f2.next()
f2: 1
>>> print'f1:', f1.next()
f1: 2
>>> print'f2:', f2.next()
f2: 2
>>> print'f2:', f2.next()
f2: 3
>>> print'f2:', f2.next()
f2: 5
return 的作用
在一个 generator function 中,如果没有 return,则默认执行至函数完毕,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。
另一个例子
另一个 yield 的例子来源于文件读取。如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:
清单 9. 另一个 yield 的例子
defread_file(fpath): BLOCK_SIZE =1024 with open(fpath, 'rb') as f: whileTrue: block =f.read(BLOCK_SIZE) ifblock: yieldblock else: return
以上仅仅简单介绍了 yield 的基本概念和用法,yield 在 Python 3 中还有更强大的用法,我们会在后续文章中讨论。
注:本文的代码均在 Python 2.7 中调试通过

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

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

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

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics





PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP is suitable for web development and rapid prototyping, and Python is suitable for data science and machine learning. 1.PHP is used for dynamic web development, with simple syntax and suitable for rapid development. 2. Python has concise syntax, is suitable for multiple fields, and has a strong library ecosystem.

VS Code can be used to write Python and provides many features that make it an ideal tool for developing Python applications. It allows users to: install Python extensions to get functions such as code completion, syntax highlighting, and debugging. Use the debugger to track code step by step, find and fix errors. Integrate Git for version control. Use code formatting tools to maintain code consistency. Use the Linting tool to spot potential problems ahead of time.

VS Code can run on Windows 8, but the experience may not be great. First make sure the system has been updated to the latest patch, then download the VS Code installation package that matches the system architecture and install it as prompted. After installation, be aware that some extensions may be incompatible with Windows 8 and need to look for alternative extensions or use newer Windows systems in a virtual machine. Install the necessary extensions to check whether they work properly. Although VS Code is feasible on Windows 8, it is recommended to upgrade to a newer Windows system for a better development experience and security.

VS Code extensions pose malicious risks, such as hiding malicious code, exploiting vulnerabilities, and masturbating as legitimate extensions. Methods to identify malicious extensions include: checking publishers, reading comments, checking code, and installing with caution. Security measures also include: security awareness, good habits, regular updates and antivirus software.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

PHP originated in 1994 and was developed by RasmusLerdorf. It was originally used to track website visitors and gradually evolved into a server-side scripting language and was widely used in web development. Python was developed by Guidovan Rossum in the late 1980s and was first released in 1991. It emphasizes code readability and simplicity, and is suitable for scientific computing, data analysis and other fields.

In VS Code, you can run the program in the terminal through the following steps: Prepare the code and open the integrated terminal to ensure that the code directory is consistent with the terminal working directory. Select the run command according to the programming language (such as Python's python your_file_name.py) to check whether it runs successfully and resolve errors. Use the debugger to improve debugging efficiency.
