在我刚开始学Python的时候,在看到生成器的时候,看到了一个叫”yield“的东东,当时没看懂后来用的也不是特别得多,(好啊,我承认这太傻了)。
首先,我们看下面这段代码:
def foo():
print("start.....")
while True:
res=yield 4
print("res is %".formate(m))
在这里,我们可以把yield理解为return(返回6,同时函数停止执行)。
拥有yield的函数不会立即执行,会返回一个生成器。
g=foo()
print(g)
print(next(g)
结果页面
每次当你调用next()方法,函数才开始真正执行。函数执行到yield 4,返回一个4,随意打印的结果是这样。
再次调用这个方法,打印的东西却发生了改变,这是为什么了。是因为next函数从上次next函数停止的地方开始重新执行。函数执行到res=yield 4的时候,只进行了yield,可以看成是return返回对象,然后函数就停止。这里并没有赋值,next()方法执行完毕。下次next()函数也同样从上次next()停止的地方再次开始。不会再打印"start"。
这就是yield的使用原理,使用生成器,能够有效的使用资源。举个例子,在我们生成一个list的时候,如果我们不知道具体该设置多大的时候,我们一般会设置的稍微大一些,这样既会收到内存的限制也极有可能造成极大的资源浪费。
我们就可以使用生成器的方式,这里使用廖雪峰老师教程上那个例子,斐波拉契数列。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
这里有一个注意点,
n,a,b=0,0,1
这里可以看作一个元组
n,a,b=(0,0,1)
a, b =(b, a + b)
不存在b的值改变之后,会影响到a的值的情况。
来看我们的代码,由于代码中有yield,函数不会立即执行,而是返回一个生成器,在调用的时候执行到yield b结束,在下次执行的时候,首先是函数的赋值,即斐波拉契数列的特性,后面的一个值就是前面两个数的和。由于while n<max且函数总是从上次函数结束的地方重新开始,这样就实现了我们所希望它实现的功能,可以获取到任何数量的连续斐波拉契数列。(可以使用for循环来迭代了)。