Python用yield from 实现异步协程爬虫

news2024/11/20 15:26:20

文章目录

  • 一、什么是yield
    • 二、yield于列表的区别
      • 三、yield from 实现协程

一、什么是yield

如果还没有怎么用过的话,直接把yield看做成一种特殊的return(PS:本质 generator(生成器))
return是返回一个值然后就终断函数了,而yield返回的是一个生成器(PS:不知道的直接看作特殊列表,看下面的代码案例)

# -*- coding: utf-8 -*-
# @Time    : 2022/11/10 16:17
# @Author  : 红后
# @Email   : not_enabled@163.com
# @blog    : https://www.cnblogs.com/Red-Sun
# @File    : 实例1.py
# @Software: PyCharm

def main():
    '''
    遍历0到4,这五个数,并分别打印
    '''
    for num in range(5):
        yield num

if __name__ == '__main__':
    for num in main():
        print(num)
    print('-'*50)
    for num in [0, 1, 2, 3, 4]:
        print(num)

在这里插入图片描述
将它看作列表用for循环遍历,就能取出其中的值。

二、yield于列表的区别

它与原来列表的区别就在于,自带的列表是固定的,而把yield看作列表的话是动态的。
具体案例描述请看代码及备注(PS:个人自己描述的,有不对的地方望各位指点)

# -*- coding: utf-8 -*-
# @Time    : 2023/01/11 15:24
# @Author  : 红后
# @Email   : not_enabled@163.com
# @blog    : https://www.cnblogs.com/Red-Sun
# @File    : 实例2.py
# @Software: PyCharm

def main():
    '''
    将yield看作一个动态列表,从yield左往右为传出数据,从又往左为传入数据。
    PS:有yield存在的那一行,需要从左往右传出数据跑一遍,数据出去以后又要从右往左带接收的数据跑一遍,一共一行跑两边(仅作者个人记忆方法)
    '''
    Python学习群:748989764
    num1 = yield
    num2 = yield
    print(num1, num2)
    yield num1 + num2
if __name__ == '__main__':
    a = main()
    # 第一个next对应第一个yield的右边为空即None,所以动态列表中加入一个参数为None,返回值为列表的-1位是None
    print(next(a))  # [None]
    # 第二个通过send方法传入一个数1,即在上一次停止的地方从右往左传入参数,所以给num1赋值为1.然后继续找下一个yield,其右边的值依旧为None,加入动态列表,此时返回值-1位依旧是None
    print(a.send(1))  # [None, None]
    # 第三通过send方法传入一个数2,即在上一次停止的地方从右往左传入参数,所以给num2赋值为2.然后继续找下一个yield,其右边的值为num1 + num2,此时num1为1,num2为2,计算得返回值-1位为3
    print(a.send(2))  # [None, None, num1 + num2]




在这里插入图片描述

三、yield from 实现协程

yield from 后面需要加可迭代对象
当它后面加上生成器(上述所说的yield这种)便可以实现生成的嵌套

  1. 老板(主程序):调用委派生成器
  2. 包工头(委派生成器):包含yield from表达式的生成器
  3. 打工仔(子生成器):生成器函数

其中委派生成器的作用:在主程序与子生成器之间建立一个双向通道。
所谓双向通道是指,主程序可以将参数通过send传递给子生成器,子生成器的yield的值也可以直接返回给主函数。(PS:委派生成器只有创建通道的作用,没有拦截数据这种功能)
也许有人会想直接用主程序调用子生成器不就行了,而对这的解释是,使用yield from作为中间过渡是为了让它帮我们进行异常处理(PS:类似写程序为了正常运行加上try一个道理)

# -*- coding: utf-8 -*-
# @Time    : 2022/11/10 15:13
# @Author  : 红后
# @Email   : not_enabled@163.com
# @blog    : https://www.cnblogs.com/Red-Sun
# @File    : coroutines.py
# @Software: PyCharm

import requests


def coroutines_spider():
    '''
    子生成器(PS: 打工仔,真正干活的)
    '''
    response = None  # 首次激活返回None,后期网页响应覆盖
    while True:
        url = yield response
        response = requests.get(url)


def appoint():
    '''
    委派生成器,委托子生成器完成具体任务 (PS: 类似包工头负责劳务派遣)
    '''
    while True:
        yield from coroutines_spider()  # 建立子生成器和主函数的双通道


def main(url_list: list):
    '''
    主函数(PS: 相当于老板,张贴招人启示)
    '''
    ul = appoint()  # 创建委派生成器
    next(ul)  # 激活它
    for url in url_list:
        response = ul.send(url)  # 将url作为参数传递进入子生成器中,返回子生成器yield出来的response
        print(response.url, response.status_code)  # 打印出response中的链接和状态码


if __name__ == '__main__':
    url_list = ['https://www.baidu.com/', 'https://www.4399.com/', 'https://cn.bing.com/', ]
    main(url_list=url_list)


在这里插入图片描述

如果您觉得文章对您有帮助,可以点赞、评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python网络编程中getservbyport和getservbyname函数的用法

在Python的网络编程中,getservbyport()函数和getservbyname()函数是socket模块中的两个函数,因此在使用这两个函数时,需要导入socket模块。1 getservbyname()函数getservbyname()函数的作用是通过指定服务的名称获取该服务对应的端口号。相关…

BI工具+方案,这是要将大数据分析包了的节奏啊

BI工具是一个为企业提供大数据智能可视化分析功能板块的平台。虽然它提供了包括智能钻取、内存行列计算、多维动态分析等多种智能数据分析功能板块,但工具毕竟是工具,要真正地为企业所用,还需要针对企业的业务发展情况、数据分析需求等制定数…

用ode45解一个带有积分的微分方程(integro-differential equations)

一、问题提出: 这个方程来源于mathworks的论坛 l 这种方程叫 integro-differential equations ,大致是带有 integral term的微分方程。积分肯定是定积分,这类方程有的是变上限的积分,上下限是x或者其他微分的函数。 按照惯例,先分析。积分区间是0-1,x是自变量,y是应…

2022年终总结——工作第五年

2022是本命年,对我来说今年勉强可以算得上是一切顺利吧。 前几年的年终总结 先验收下去年的期望吧 去年的期望还是挺多的嗷🙃 1、关于订婚和云南一周游 ✅ 今年大概2月底开始上海疫情开始变得很严重,然后就是漫长的三个月封控,…

1.1.3 java学习的环境准备

文章目录1 相关文件准备及下载1.1 JDK下载1.2 开发工具下载1.2.1 eclipse1.2.2 idea2 JDK安装及配置2.1 JDK配置方法一2.2 JDK配置方法二3 eclipse软件安装及配置4 JDK JRE JVM解释:5 关于手写代码1 相关文件准备及下载 1.1 JDK下载 Oracle公司为常见的计算机系统…

【论文速递】ECCV2022 - ConMatch:置信度引导的半监督学习

【论文速递】ECCV2022 - ConMatch:置信度引导的半监督学习 【论文原文】:ConMatch: Semi-Supervised Learning with Confidence-Guided Consistency Regularization 获取地址:https://arxiv.org/abs/2208.08631博主关键词: 半监…

P8630 [蓝桥杯 2015 国 B] 密文搜索

题目描述 福尔摩斯从 X 星收到一份资料,全部是小写字母组成。 他的助手提供了另一份资料:许多长度为 88 的密码列表。 福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。 请你编写一个程序,从第一份资料中搜索可能隐藏密码…

八大排序算法(C语言实现)

文章目录:1.排序的概念2.常见八大排序算法3.插入排序3.1直接插入排序3.2希尔排序4.选择排序4.1直接选择排序4.2.堆排序5.交换排序5.1冒泡排序5.2快速排序5.2.1快排递归实现5.2.1.1Hoare法(霍尔法)5.2.1.2挖坑法5.2.1.3双指针法5.2.2快排迭代实…

最火的聊天回复神器

客服高效回复容易收获用户的好感,也更容易将客户转化成功,借助聊天回复神器,可以助力客服高效快捷地回复。 前言 经常网购的用户,一定会发现在联系客服咨询产品相关问题时,刚把问题发出去,马上就可以收到客…

three.js入门-一些基础理论|大帅老猿threejs特训

前言 参加了threejs直播课。 本篇文章为入门理论部分笔记。 可以学到什么: 一、软能力 1. 系统全流程理解web3D 应用/数字孪生/元宇宙,程序开发与3D美术资源制作 2. 建立与3D美术团队良好沟通协作能力 3. 良好把控3D画面效果和性能平衡 4. 培养程…

数据分析师:星图Stagraph 2.1 Crack

Stagraph 是一个用于数据导入 - 数据整理 - 数据可视化的复杂软件工具。面向数据工程师、数据分析师、数据科学家、统计学家和其他“数据专业人员”的专业软件。在简单易用的可视化界面中提供最新数据科学工具的强大功能。采集 by Ω578867473 降低 降低处理数据的复杂性。使用…

作业帮:探索多云架构下的数据库集群解决方案

导语:面对业务多元、数据海量、数据库种类多样、多云架构复杂等痛点,该如何制定既能解决问题又能降本增效的数据库升级方案?作业帮作为实践者,从四方面分享其数据库选型过程与思考。以下为作业帮DBA刘强在DTCC大会中的讲述。 嘉宾…

移动端自动化python使用appium包登录qq

听标题挺高大上的,其实内容还是脚本小子的高度。。。 为了写个月报一下午抓紧学点东西,好凑点字数,汗。。。 为啥学这个内容,因为找内容的时候翻csdn翻到一个自动抢红包的,就是用的这个技术,前面实验挺好&a…

React Native 三端同构在雪球的实践

随着移动互联网的迅猛发展,目前市面上「端」的形态多种多样,iOS、Android 、H5、微信小程序等各种端大行其道,同一个业务需求往往又需要在多端上去实现,针对不同端去编写多套代码的成本显然非常高。雪球大前端团队将今年在跨端能力…

提取DC综合report_constrain all violator中big neg slack

问题描述 在综合前几版中&#xff0c;通过report_constrain -all_violator命令到得到的违反数量非常多&#xff0c;但暂时只关注比较大的setup/hold违例。 &#xff08;1&#xff09;我们希望提取 < -1.0的违例 &#xff08;2&#xff09;需要把多行合并到一行。 &#xf…

学习python,我使用代码悄悄集齐了五福~哎嘿嘿

啊哈哈哈哈&#xff0c;我又又又来啦 这不是快春节了吗&#xff0c;支付宝等一些集五福活动又又又又一次的到来 今天呢&#xff0c;写一个啥呀我也不晓得&#xff0c;啊哈哈哈哈哈 今天写一个%90会出敬业福哦&#xff0c;啊哈哈哈哈 1.制作文字福 这个其实挺“简单”的&…

如何计算单元测试的覆盖率

一、概念 单元测试的覆盖率有&#xff1a;语句覆盖率&#xff08;即行覆盖率&#xff09;、分支覆盖率、条件覆盖率、分支条件覆盖率、路径覆盖率等。 语句覆盖率 所谓语句就是那些非分支、非判断的语句。 计算公式&#xff1a;程序执行到的语句总数 / 全部语句的总数 分支覆…

C语言程序设计易混、易错知识点(中篇)

注&#xff1a;个别题目未给ABCD&#xff0c;只需要了解知识点即可&#xff1b;另外排版可能有点乱&#xff0c;望知悉 在printf中的%作为转义符&#xff0c;两个%才相当于1个% free掉一个指针后&#xff0c;指针的值是不会自动置为NULL的&#xff0c;当然其指向的内存已经被释…

C语言从入门到放弃——字符串和内存操作函数

字符串&#xff0c;是一种由双引号引起的一整串字符&#xff0c;在C语言中&#xff0c;字符串是没有类型的&#xff0c;通常我们将字符串放在字符数组当中&#xff0c;同时&#xff0c;我们对于字符串的操作是很频繁的&#xff0c;因为对于字符串的操作频繁&#xff0c;所以C语…

为什么需要预选器?

无论是采用模拟IF处理的传统频谱仪&#xff0c;还是采用数字IF处理的现代频谱仪&#xff0c;都是扫频式架构&#xff0c;通过第一级本振(LO)的调谐实现射频的扫频测试。熟悉频谱仪架构的朋友都了解&#xff0c;在第一级混频器之前都会存在一个预选器&#xff0c;如图1所示&…