起首,假如你还没有对yield有个开端分熟悉,那末你先把yield看作“return”,这个是直观的,它起首是个return,一般的return是什么意义,就是在递次中返回某个值,返回今后递次就不再往下运转了。看作return今后再把它看作一个是生成器(generator)的一部分(带yield的函数才是真正的迭代器),好了,假如你对这些不邃晓的话,那先把yield看作return,然后直接看下面的递次,你就会邃晓yield的悉数意义了:
def foo(): print("starting...") while True: res = yield 4 print("res:",res) g = foo() print(next(g)) print("*"*20) print(next(g))
就这么简朴的几行代码就让你邃晓什么是yield,代码的输出这个:
starting... 4 ******************** res: None 4
我直接诠释代码运转递次,相当于代码单步调试:
1.递次最先实行今后,因为foo函数中有yield关键字,所以foo函数并不会真的实行,而是先获得一个生成器g(相当于一个对象)
2.直到挪用next要领,foo函数正式最先实行,先实行foo函数中的print要领,然后进入while轮回
3.递次遇到yield关键字,然后把yield想想成return,return了一个4今后,递次住手,并没有实行赋值给res操纵,此时next(g)语句实行完成,所以输出的前两行(第一个是while上面的print的效果,第二个是return出的效果)是实行print(next(g))的效果,
4.递次实行print(""20),输出20个*
5.又最先实行下面的print(next(g)),这个时刻和上面谁人差不多,不过差别的是,这个时刻是从适才谁人next递次住手的处所最先实行的,也就是要实行res的赋值操纵,这时刻要注意,这个时刻赋值操纵的右侧是没有值的(因为适才谁人是return出去了,并没有给赋值操纵的左侧传参数),所以这个时刻res赋值是None,所以接着下面的输出就是res:None,
6.递次会继承在while里实行,又一次遇到yield,这个时刻一样return 出4,然后递次住手,print函数输出的4就是此次return出的4.
到这里你能够就邃晓yield和return的关联和区别了,带yield的函数是一个生成器,而不是一个函数了,这个生成器有一个函数就是next函数,next就相当于“下一步”生成哪个数,这一次的next最先的处所是接着上一次的next住手的处所实行的,所以挪用next的时刻,生成器并不会从foo函数的最先实行,只是接着上一步住手的处所最先,然后遇到yield后,return出要生成的数,此步就完毕。
def foo(): print("starting...") while True: res = yield 4 print("res:",res) g = foo() print(next(g)) print("*"*20) print(g.send(7))
再看一个这个生成器的send函数的例子,这个例子就把上面谁人例子的末了一行换掉了,输出效果:
starting... 4 ******************** res: 7 4
先大抵说一下send函数的观点:此时你应当注意到上面谁人的紫色的字,另有上面谁人res的值为何是None,这个变成了7,究竟为何,这是因为,send是发送一个参数给res的,因为上面讲到,return的时刻,并没有把4赋值给res,下次实行的时刻只好继承实行赋值操纵,只好赋值为None了,而假如用send的话,最先实行的时刻,先接着上一次(return 4今后)实行,先把7赋值给了res,然后实行next的作用,碰见下一回的yield,return出效果后完毕。
5.递次实行g.send(7),递次会从yield关键字那一行继承向下运转,send会把7这个值赋值给res变量
6.因为send要领中包括next()要领,所以递次会继承向下运转实行print要领,然后再次进入while轮回
7.递次实行再次遇到yield关键字,yield会返回背面的值后,递次再次停息,直到再次挪用next要领或send要领。
这就完毕了,说一下,为何用这个生成器,是因为假如用List的话,会占用更大的空间,比如说取0,1,2,3,4,5,6............1000
你能够会如许:
for n in range(1000): a=n
这个时刻range(1000)就默许生成一个含有1000个数的list了,所以很占内存。
这个时刻你能够用适才的yield组合成生成器举行完成,也能够用xrange(1000)这个生成器完成
yield组合:
def foo(num): print("starting...") while num<10: num=num+1 yield num for n in foo(0): print(n)
输出:
starting... 1 2 3 4 5 6 7 8 9 10
xrange(1000):
for n in xrange(1000): a=n
个中要注意的是python3时已没有xrange()了,在python3中,range()就是xrange()了,你能够在python3中检察range()的范例,它已是个<class 'range'>了,而不是一个list了,毕竟这个是须要优化的。
以上就是python中yield的用法引见(附代码)的细致内容,更多请关注ki4网别的相干文章!