yield是Python中比较有意思,也比较有难度,我也是阅读代码的过程中发现了这个函数的好处,yield是生成的意思,但是在python中则是作为生成器理解,生成器的用处主要可以迭代,这样简化了很多运算模型。
关于yield可以参看《Python 深入理解yieldhttp://www.jb51.net/article/15717.htm》这篇文章中比较详细的描述了yield的基本原理和问题。
yield在python2.5以后不再是一个句子,而是一个表达式,表达式是有返回值的,就如同我们在C语言中的if(expression)一样。
当函数中存在yield以后,那么该函数就不在是普通的函数了,而是一个生成器。当该函数被调用时,并不会自动执行,而是暂停中,可以从下面的代码中得到体现。
>>> def mygenerator():
... print 'start....'
... yield 5
...
>>> mygenerator()
<generator object mygenerator at 0xa2084b4>
从上面的结果可以知道,在mygenerator()之后,并没有打印出starting....说明存在yield的函数被调用的时候是没有运行的,可以认为是暂停的状态,因此需要重新启动程序。这时采用next()即可实现函数的启动。
>>> g = mygenerator()
>>> g.next()
start....
5
>>> g.next()
Traceback (most recent call last):
File "", line 1, in <module>
StopIteration
mygenerator()中创建了对象g,这时需要next()启动程序的运行,出现了上面的结果,也就是完成了程序的重新运行,但是遇到yield后就会再次停止,从上面的效果我们可以知道,在第一次运行g.next()之后,打印,然后遇到了yield 5,这时候就会停止,再次g.next()之后,后面没有yield,说明迭代过程结束,抛出了StopIteration异常。
>>> def mygenerator2():
... print 'starting ....'
... yield 5
... print 'middle ....'
... yield 12
... print 'end ....'
...
>>> g1 = mygenerator2()
>>> g1.next()
starting ....
5
>>> g1.next()
middle ....
12
>>> g1.next()
end ....
Traceback (most recent call last):
File "", line 1, in <module>
StopIteration
上面的代码也说明我的分析是正确的,第一次调用next()就执行到yield 5,暂停,然后next(),重新启动,并执行到yield 12,然后再次next()之后就会抛出错误,从上面打印出来的字符串就可知道。但输出中我们还发现了5,12等这是为什么呢?我认为这实质上是yield 5的返回值,因为表达式也会存在值的问题,这是肯定会输出表达式的值。
那么这是否可以认为yield 5的返回值一定是5吗?实际上并不是这样,这个与send函数存在一定的关系,这个函数实质上与next()是相似的,区别是send是传递yield表达式的值进去,而next不能传递特定的值,只能传递None进去,因此可以认为g.next()和g.send(None)是相同的。
>>> def mygenerator2():
... print 'starting ....'
... m = yield 5
... print m
... print 'middle ....'
... d = yield 12
... print d
... print 'end ....'
...
>>> g1 = mygenerator2()
>>> g1.next()
starting ....
5
>>> g1.send('pass expression')
pass expression
middle ....
12
>>> g1.next()
None
end ....
Traceback (most recent call last):
File "", line 1, in <module>
StopIteration
>>> g1 = mygenerator2()
>>> g1.next()
starting ....
5
>>> g1.send('pass expression')
pass expression
middle ....
12
>>> g1.send('pass expression')
pass expression
end ....
Traceback (most recent call last):
File "", line 1, in <module>
StopIteration
从上面的效果可知道,可以知道,next()的传递的实质上就是None,而send传递进来的pass expression也作为表达式yield n的返回值,因此我们可以知道,yield的返回值并不是n的值,而是和send()传递进去的参数密切相关。实质上yield n表达式的返回值是指上就是send()函数传递进去的参数,了解到这一点是非常重要的。
关于send()和next()函数的返回值也是需要我们详细去分析的,从下面的代码可以知道:
>>> def returntest():
... m = yield 5
... print m
... n = yield 10
... print n
... h = yield 15
... print h
...
>>> t = returntest()
>>> n = t.next()
>>> n
5
>>> n = t.next()
None
>>> n
10
>>> n = t.next()
None
>>> n
15
>>> t = returntest()
>>> n = t.next()
>>> n
5
>>> n = t.send(40)
40
>>> n
10
>>> n = t.send(50)
50
>>> n
15
从上面的代码我们可以知道next()和send()的返回值是与yield n的n密切相关,实际上就是yield n的n值。而yield的返回值就是send()传递进来的非None参数。
有一段经典的代码是不得不去分析的:
>>> def addlist(alist):
... for i in alist:
... yield i + 1
...
这段代码中实际上就是运用了上面几个函数的返回值,因为for ...in句式实质上就是一个迭代器,也就是说alist[i] = addlist.next(),采用next的返回值也就是yield n的参数值n,也就是完成了alist[i] = i+1.这就是返回值的灵活运用,这段代码被灵活的运用于Python的迭代器中。
总结:
yield 的返回值是send(参数)中的参数,比如send(10),那么yield的返回值就是10
send(None)和next()的意思是一样的,但是因为send不能传递None量,因此这才突显出了next()函数的作用,这两个函数的返回值通常就是yield n中的参数n。
存在yield的函数不是普通的函数,而是生成器,只有调用send()或者next()函数以后才能执行,否则就是暂停的形式,这与其他函数是存在差别的。
相关推荐
Python中的`yield`关键字是其语法的一大特色,它在生成器(Generator)中扮演着核心角色。生成器是一种特殊的迭代器,它允许我们定义一个函数,该函数可以在执行过程中暂停并保存状态,以便下次调用时能从暂停的地方...
### Python中`yield`的关键概念与使用详解 #### 前言 在Python编程语言中,`yield`关键字提供了一种高效且灵活的方式来处理大型数据集或无限序列,尤其是在涉及迭代器、生成器等概念时更为突出。本文将详细介绍`...
yield在python中初学时,觉得比较难理解。yield的作用: ①返回一个值、②接收调用者的参数 分析下面的代码: #!/usr/bin/env python3 # -*- coding:utf-8 -*- def consumer(): r = '' while True: n = yield r ...
生成器(Generator)是Python中一种特殊的迭代器(Iterator),它的作用是允许用户在迭代过程中暂停和恢复迭代过程。生成器的关键特性是它允许以一种节省内存的方式来处理大量的数据。在Python 3.6及更早的版本中,...
在Web开发、数据分析、人工智能、网络编程、自动化运维等领域,Python都有着不可忽视的地位。 【开始使用Python】 要开始使用Python,首先需要安装Python解释器,然后可以通过交互式环境(如IDLE)进行尝试。...
本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下: yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。 只是粗略的知道yield可以用来为一个函数返回值塞...
主要介绍了Python协程 yield与协程greenlet简单用法,简要讲述了协程的概念、原理,并结合实例形式分析了Python协程 yield与协程greenlet基本使用方法,需要的朋友可以参考下
12. **性能优化**:学习Python的性能分析工具,如cProfile,以及如何通过优化算法、使用C扩展或NumPy等科学计算库来提升代码执行效率。 通过阅读《Python进阶(Intermediate Python)》,读者不仅可以巩固已有的...
yield的功能类似于return,但是不同之处在于它返回的是生成器。 生成器 生成器是通过一个或多个yield表达式构成的函数,每一个生成器都是一个迭代器(但是迭代器不一定是生成器)。 如果一个函数包含yield关键字,...
### Python中xrange与yield的用法实例分析 #### 一、range与xrange的区别 在Python中,`range` 和 `xrange` 都是用来生成整数序列的内置函数,但它们之间存在一些重要的区别。 ##### range - **功能**:`range()`...
在Python编程语言中,"utils"通常指的是工具模块或实用函数集合,它们包含了各种常用的、跨领域的功能。这里我们将深入探讨Python中的一些常见方法和工具,以帮助开发者提高效率和代码质量。 首先,让我们了解...
- 如果不在默认路径中,可能需要指定完整路径如`/usr/local/bin/python3.4`。 - **参数传递**:可以通过命令行传递参数给Python解释器,例如`python3.4 script.py arg1 arg2`。 #### 三、交互模式 - **简介**:...
Python的`dis`模块允许开发者查看和分析字节码,而一些库,如`jump`或`greenlet`,则提供了在运行时修改字节码的能力,从而实现类似goto的功能。这种方法通常用于创建复杂的循环结构或者在程序执行中改变流程,但应...
本文将探讨如何利用Python中的`yield`关键字及其相关机制来实现异步操作的同步化处理。这种方法不仅能够提升代码的可读性和可维护性,还能在一定程度上简化复杂的异步流程。 #### 二、Python Yield机制简介 `yield`...
Python 3.8.2还强化了对类型提示(type hints)的支持,这有助于代码的静态分析和自动完成。 面向对象编程在Python中也非常强大。Python支持类的定义,类方法,实例方法,静态方法,以及多重继承。__slots__特性...
在 parse 方法中,我们可以使用 CSS 选择器来解析 HTML 页面,获取汽车价格信息,并将其yield出来。最后,我们可以使用 Scrapy 的 Request 对象来继续爬取下一页。 三、数据清洗与处理 在爬取到数据后,我们需要对...
本篇文章将详细介绍生命游戏的基本概念、Python中的实现逻辑以及相关代码分析。 ### 生命游戏基本概念 生命游戏(Game of Life)是一种零玩家策略游戏,由数学家约翰·康威(John Horton Conway)在1970年代提出。...
通过以上分析,我们可以看出`yield`关键字在Python中具有重要的作用,它不仅简化了代码编写,还极大地提高了程序的性能和资源利用率。理解和掌握`yield`的使用对于进行高效的数据处理至关重要。