为了方便追小说更新撸了一个基于scrapy的爬虫。在实现过程当中使用到了 yield,网上对其的文字描述都很难让人理解。经过Debug代码才了解调用顺序,进而理解了它使用方法。python
咱们能够用一个等式来形容其做用:shell
yeild 函数 = return 生成器(generator) 用同步方式写异步异步
生成器 = 可迭代的函数scrapy
正常状况下咱们能够这样迭代一个列表函数
# encoding:UTF-8
def call(i):
return i * 2
array = [call(0),call(1),call(2)]
for i in array:
print(i, ",")
复制代码
打印结果:工具
0 ,
2 ,
4 ,
复制代码
以上的代码,适合在数据量小的状况下运行,假如在海量数据的场景下,这样的写法将对内存形成很大的压力。由于列表内全部数据都同时加载在内存中。spa
而python的生成器则完美的解决了这一问题,它不须要将全部的值同时加载,它只提供了一个生成数据的方式, 并且它是可迭代debug
# encoding:UTF-8
def call(i):
return i * 2
def generator(n):
for i in range(n):
yield call(i)
for i in generator(3):
print(i, ",")
复制代码
打印结果:code
0 ,
2 ,
4 ,
复制代码
能够看到 generator 作的事情很简单:循环生成了0到2相对应的值。而yield的做用就是提供生成器给外部。cdn
这样作的好处就在于每次值都是按需生成的,且生成完不会停驻在内存中。
值得一提的就是yield的调用顺序也是很清奇的,它的调用顺序和咱们常见的简单的自上而下。 咱们在以上的demo中加入几行print
# encoding:UTF-8
def call(i):
return i * 2
def generator(n):
for i in range(n):
yield call(i)
print("generate i=", i)
print("end.")
for i in generator(3):
print(i, ",")
复制代码
在咱们的预期中,咱们的预期执行顺序是
generate i= 0
0 ,
generate i= 1
2 ,
generate i= 2
4 ,
end.
复制代码
而它的结果运行结果倒是这样:
0 ,
generate i= 0
2 ,
generate i= 1
4 ,
generate i= 2
end.
复制代码
那么意味着它的执行顺序是这样:
能够发现,只要执行到yield关键字都会先return,在外层执行完毕后,再执行yield以后下一条指令。
当咱们处理数据量大的事物的时候,能够效仿关键字yield这样的思路:持有索引或者其余可检索的id,在须要的时候再去经过构造器或者其余工具获取