再谈Python中的yield,return的区别
(2018-03-25 11:16:14)
标签:
python编程迭代器和生成器yield和return |
分类: Python |
初次学习Python,一定对yield的神奇功能感到好奇,又不好理解。下面用实际案例来说明yield和return的区别。
观点1:
return是函数返回值,当执行到return,后续的代码不再执行;
yield是创建迭代器iteral,称之为生成器generator,让函数生成一个结果序列,而不仅仅是一个值,可以用for来遍历,有点事件触发的意思。可用现实的一种实物来理解:水车,先yield来装入数据、产出generator object、使用next()来释放;好比水车转动后,车轮上的水槽装入水,随着轮子转动,被转到下面的水槽就能将水送入水道中流入田里。好处是不用一次计算所以元素,而是用一次算一次,可以节省大量空间。
Exam-1
def
if __name__ ==
#上两句可以写成一句 print([next(ty) for I in range(10)])
Exam-2
def fib_yield():
fib2 = fib_yield()
print([next(fib2)
如果要用send(),必须先用next()调用一次:
next(fib2)
print([fib2.send(i)
观点2:
return对应的是普通函数,函数可以多次进入,同时内部的状态信息会进行保存,执行完毕以后控制权移交给父函数,函数的上下文就此销毁;
yeild对应的是协程(Coroutine),长得像函数,实际不是函数,而是一个具有迭代功能的生成器。其他的地方几乎没有函数的影子,只是起了一个生成器的作用,所以你无法用执行语句的方法调用他,必须用next()和send()函数进行调用。只要一个函数包含yield语句,就是具有迭代器功能的生成器。多用于异步或者递归。
next() 调用使生成器函数一直运行到下一条yield语句为止, 此时next()将返回值传递给yield,而且函数将暂时中止执行,再次调用next()时,函数将继续执行yield之后的语句。此过程将持续到函数返回为止。通常会使用一个for循环调用next()。
什么是协程?
函数运行时要使用一组输入参数,但是,也可以将函数编写为一个任务,从而能处理发送给它的一系列输入,这类函数称为协程。
Exam-3
def matches(mtext):
要使用这个函数,首先要调用它,向前执行第一条yield语句,然后使用send()函数给它发送数据。
match.send("quit")
match.close()
观点3:
从控制权来说,函数遇到return时,控制权交给主线程,然后没这个函数什么事了。如果遇到yield,控制权只是暂时交给主线程,函数继续在那等着。另外,函数里出现yield就自动变成生成器。
生成器是基于UNIX中处理管道、流或数据流编写程序的一种极其强大的方式。
下面的生成器用于在很多行中查找特定的子字符串:
Exam-4
def grep(lines, search):
更强大的例句,参见廖雪峰的官方微博:filter的强大用法
https://www.liaoxuefeng.com/wiki/0014316089557264a6b34895