请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

yield 和 return的问题

bobby老师再次看您的视频发现一个小问题想问您一下,关于yield和return的问题

问题1:
在crawler全站规则匹配爬取中 在parse_job中最后您用的是return 但是其他项目基本都是yield,这里使用return是否会降低效率

问题2:
我在搜索问题1的时候发现有一种说法是yield后面可以用类变量,return后面不可以,是这样吗

问题3:
您在某一集的视频里说需要yield一个列表,类似这样 yield [Request()] 还特意强调了需要yield列表,但是没有说为什么,想问您一下原因(好像是某次改写start_requests方法)

以上,周边没有电脑,排版有些乱,用手机码的字,还请老师见谅..

正在回答

1回答

这样的,这个其实属于python的生成器的问题, 生成器函数中可以yield也可以return,但是return之后函数就结束了。yield之后函数不会结束也是会暂停等待scrapy的engine下一次启动,所以两个都可以互相使用,具体应该使用什么需要考虑你的具体的逻辑,比如parse_job最后既可以使用return也可以使用yield,因为只有一个item需要传递出去。当然如果这个函数中你可能解析出来request也也有item需要交出去 那么就需要使用yield,因为yield可以立即将结果传递出去而不会导致函数退出, start_requests函数最后的结果课程强调的是一定要yield一个request出去 或者要使用return 列表的方式。,注意这里的区别:

    1. yield可以直接一个request

    2. return必须是列表,哪怕是空列表,如果只有一个request也需要是列表

为什么会这样呢?你如果懂了生成器就知道了。生成器是可以使用for循环调用的,所以scrapy engine是会对start_requests的结果进行for循环遍历的,如果函数是一个生成器 使用for循环就不会出问题。但是如果return 了一个request就无法for循环就会报错

0 回复 有任何疑惑可以回复我~
  • 提问者 慕数据8096394 #1
    超级感谢老师(这里无法打表情)超级感谢,想通了这个问题,感觉能开心好几天,困扰了我好久的一个问题了,总结老师的回答如下,也方便之后的同学查看:
    
    1. 用yield其实就是应对同一个回调函数下有多个输出的情况:要么返回很多Request,要么既要返回Request又要返回Item的情况
    
    2. 如果某一个回调函数就只是返回item,或者只是返回一个Request,那么用return还是yield就没有区别了,性能也没有区别
    
    3. 只是注意return Request的时候需要是列表,因为需要遍历返回结果(yield 不用列表,因为遍历的时候自然就是可迭代的)
    回复 有任何疑惑可以回复我~ 2020-05-06 12:12:49
  • bobby 回复 提问者 慕数据8096394 #2
    正解,
    回复 有任何疑惑可以回复我~ 2020-05-09 09:15:31
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信