昨天看了许多条博客,同时问了大佬一些心中的疑惑,对这个yield心中有了些许的理解,虽然可能没有理解到他的内涵,但至少在使用时该如何使用仍是有了些许了解,所以决定写出来分享python
首先咱们得了解一个东西叫迭代器,一般的for…in…循环中,in后面是一个数组,这个数组就是一个可迭代对象,相似的还有链表,字符串,文件。它能够是mylist = [1, 2, 3],也能够是mylist = [x*x for x in range(3)]。 它的缺陷是全部数据都在内存中,若是有海量数据的话将会很是耗内存。他们能够从内容从中一个一个的读取,这就是迭代。数组
接着咱们须要了解迭代器里的一个特殊——生成器,生成器也是一个能够迭代的对象,可是生成器每一个只能迭代一次(至于为何后面会讲),这是他特殊的缘由。由于用的时候才生成。好比 mygenerator = (x*x for x in range(3)),注意这里用到了(),它就不是数组,而上面的例子是[]。生成器这里用的是小括号,而迭代器用的是中括号。函数
好了接下来得讲下他们的方法,无论是生成器仍是迭代器,均可以使用他的方法,就是next(这个方法在python2里面是使用的时候是方法c.next(),在python3里面变为了函数next(c)),可是因为迭代器能够自动进行,至关于里面已经内嵌了这个方法,生成一个迭代器他能够自动日后迭代,可是生成器不同,生成一个生成器的时候,他是定在初始状态的,这就须要咱们的next来一步一步推进他们。他们还有一种方法是send(),这个至关于在next功能的基础上,再加了一个传递的功能,他能够传递参数给yield表达式,因此send(None)就至关于next参数。spa
如今咱们能够来谈谈yield了,其实yield就至关于一个return,只是return返回的是值,可是yield返回的是生成器,除了这点其余都同样,因此return也好yield也好都只能用在函数中,不要出现这种代码了:code
for i in range(5): return i
因此要试验yield要在函数里实验,咱们能够试着构造一个生成器:对象
def y_test(x): for i in range(x): yield i print(i) y_test(3)
咱们试着输出结果,却发现没有输出,这是由于生成了一个生成器,并且生成的生成器是在初始状态,我们还没给他下指令他就不会开始生成,因此如今咱们给他一个指令blog
def y_test(x): for i in range(x): yield i print(i) y_test(3) c = y_test(3) next(c)
诶,咱们如今改造了后为何仍是显示没有输出,如今生成器是生成了但别忘了这是一个至关于return的函数,他实际上已经把值传进了内存,可是没有显示出来,咱们能够用一个print把他显示出来内存
def y_test(x): for i in range(x): yield i print(i) y_test(3) c = y_test(3) print(next(c))
如今咱们就会看到它显示出来了(range这个函数生成了从1到n-1得数,好比range(5)生成了0.1.2.3.4)ci
好,那么接下来你可能又会有问题了,为何这个只生成了第一个数啊,不该该是遍历把全部的输出来吗,这就是yield的做用了,这是由于生成了生成器,咱们next他一次,他也就只会往前走一次,第二次就不走了,那咱们就再来一次next看看会怎样:字符串
def y_test(x): for i in range(x): yield i print(i) y_test(3) c = y_test(3) print(next(c)) print(next(c))
这时候出现了三个值,这就要继续解释yield的缘由了,每次咱们使用一次next,他都会执行到第一个yield结束的位置,第二次用next推进他执行时,他就会从上一个yield执行完成的位置开始执行到下一个yield执行完成,在这里是在for循环里,下一个yield就是第二个循环里的yield,虽然是同样的语句,可是他们所在的循环次数不同,因此yield就至关于返回值的同时,记住当前运行到的位置,下一次运行就从上一次运行到的位置开始运行,这也是为何他只能遍历一遍的缘由,由于在第二个next执行的时候,第一个next里的内容已经被抛掉了,内存里只有第二个yield执行的内容。
咱们能够再看一例子来加深理解:
def f(x): for i in range(x): yield i print (i) yield i+1 c = f(5) print(next(c)) print(next(c)) print(next(c))
根据上文的理解会输出四个值
符合前面的猜测,最后让咱们来用一个斐波那契数列的例子来结束全文吧:
def fib(x): yield 1 a,b = 1,1 while x: a,b = b,a+b yield a x=x-1 for i in fib(5): print(i) >>>runfile('F:/Python/exercise/pygame/yield_text.py', wdir='F:/Python/exercise/pygame') 1 1 2 3 5 8