前言
yield from 是 Python3.3 后新加的语言结构。yield from的主要功能是打开双向通道,把最外层的调用方法与最内层的子生成器连接起来。这两者就可以进行发送值和返回值了,yeild from结构的本质是简化嵌套的生产器,不理解这个是什么意思的话,下面我将用几个例子来对其使用方法进行讲解。
yield from 是 Python3.3 后新加的语言结构。yield from的主要功能是打开双向通道,把最外层的调用方法与最内层的子生成器连接起来。这两者就可以进行发送值和返回值了,yeild from结构的本质是简化嵌套的生产器,不理解这个是什么意思的话,下面我将用几个例子来对其使用方法进行讲解。
简化for循环中的yeild
首先看一个
def gene(): for c in 'AB': yield c #遇到yeild程序返回循环,下次从yeild后面开始。 for i in range(3): yield i if __name__=="__main__": list(gene())#list内部会预激生成器
输出
['A','B','0','1', '2']
上面的代码可以简写成
def gene(): yield from 'ab' yield from range(3) if __name__=="__main__": list(gene())
通过上面的代码我们可以知道,yield from 可以简化for循环里的yield表达式。当然yeild from的功能不仅仅是可以简化for循环而已,要是这样的话也就不值得,单独写一篇文章来介绍了。
我们仔细观察,简化后的式子有两个yeild from,同样的也就是说如果有10个for循环的yeild生成式,我们需要写10个yeild from,此时我们要记得在python中如果重复的代码出现了两次以及以上就该考虑优化了。好了接下来我们看一个优化后的例子。
通过yield from链接可迭代对象
def chain(*args): for i in args: # for m in i: # yield m yield from i p = list(chain("1234", "AB", [1, 2, 3, 4, 5])) print(p)
输出
['1', '2', '3', '4', 'A', 'B', 1, 2, 3, 4, 5]
这里对之前的例子做了个优化处理,通过*args可变参数,配合后面的for循环进行了多个可迭代对象的链接处理。下面来看一个复杂点的例子:
来自Python cookbook 3 ,github源码地址
https://github.com/dabeaz/python-cookbook/blob/master/src/4/how_to_flatten_a_nested_sequence/example.py)
扁平化处理嵌套型的数据
# Example of flattening a nested sequence using subgenerators from collections import Iterable def flatten(items, ignore_types=(str, bytes)): for x in items: if isinstance(x, Iterable) and not isinstance(x, ignore_types): yield from flatten(x) else: yield x items = [1, 2, [3, 4, [5, 6], 7], 8] # Produces 1 2 3 4 5 6 7 8 for x in flatten(items): print(x) items = ['Dave', 'Paula', ['Thomas', 'Lewis']] for x in flatten(items): print(x)
接下来通过说一下开篇提到的子生产器和调用方以及新的词委托生成器。
了解几个概念
yield from x 表达式对x对象做的第一件事是,调用 iter(x),从中获取一个迭代器。所以x是可迭代对象。上面的例子中的x如果是可迭代对象就会执行,yield from flatten(x).
PEP380 的标题是 ”syntax for delegating to subgenerator“(把指责委托给子生成.器的句法)。由此我们可以知道,yield from是可以实现嵌套生成器的使用。
yield from在看接下来的代码之前我们必须知道这几个概念:
委派生成器
包含yield from 表达式的生成器函数
子生成器
从yield from 部分获取的生成器,含义yield的。
调用方
调用委派生成器的客户端(调用方)代码,也就是运行入口。
ok,了解了这些我们看接下来的一个例子。
使用yeild from写一个异步爬虫
import requests from collections import namedtuple ① Response = namedtuple("rs", 'url status') ② # 子生产器 def fecth(): ③ res=[] while 1: url = yield ④ if url is None: ⑤ break req = requests.get(url) res.append(Response(url=url, status=req.status_code)) return res #委派生成器 def url_list(l, key): while 1: ⑥ l[key] = yield from fecth() ⑦ #调用方 def main(): l = {} u = ["http://www.baidu.com", "http://www.cnblogs.com"] for index, url in enumerate(u): if index == 0: ul = url_list(l, index) next(ul) ⑧ ul.send(url)⑨ ul.send(None)⑩ return l if __name__ == '__main__': res = main() print(res)
接下来对上面的标准进行解释:
① 引入一个具名元组,可以后面实现一个简单的类。
② 对请求参数做一个格式化处理,后面通过获取属性即可。
③一个协程,通过requests模块可以发起网络请求。
④main函数的发送的值绑定到这里的url上
⑤ url为None即没有url的时候结束循环的。
⑥这个循环每次都会新建一个fetch 实例,每个实例都是作为协程使用的生成器对象。
⑦ url_list发送的每个值都会经由yield from 处理,然后传给fetch 实例。url_list会在yield from表达式处暂停,等待fetch实例处理客户端发来的值。fetch实例运行完毕后,返回的值绑定到l[key] 上。while 循环会不断创建fetch实例,处理更多的值。
⑧激活url_list生成器⑨把各个url以及其序列号index,传给url_list传入的值最终到达fetch函数中,url_list并不知道传入的是什么,同时url_list实例在yield from处暂停。直到fetch的一个实例处理完才进行赋值。
⑩关键的一步,# 把None传入url_list,传入的值最终到达fetch函数中,导致当前实例终止。然后继续创建下一个实例。如果没有ul.send(None),那么fetch子生成器永远不会终止,因为ul.send()发送的值实际是在fetch实例中进行,委派生成器也永远不会在此激活,也就不会为l[key]赋值
参考资料:
流畅的python 第16章 PEP 380-- Syntax for Delegating to a Subgenerator How Python 3.3 "yield from" construct works
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 邱锋泽.2024-COlOR.Free【发现梦想】【FLAC分轨】
- 群星 《10年朋友Vol.8》滚石台湾版[WAV+CUE][1.G]
- 群星《2024好听新歌31》十倍音质 U盘音乐 [WAV分轨][1.1G]
- 群星《全天后》华纳[WAV+CUE][1.1G]
- 许乐《声愿HQCD》[正版原抓WAV+CUE]
- 黄凯芹《给你留念》头版限量编号MQA-UHQCD2024[低速原抓WAV+CUE]
- 黑鸭子2008-今生最爱[首版][WAV+CUE]
- 彭海桐.2000-好好想想你【SONY】【WAV+CUE】
- 群星.1995-亚洲电视剧集主题曲大全·乐作剧2CD【滚石】【WAV+CUE】
- 林强.1992-春风少年兄【魔岩】【WAV+CUE】
- 世界顶级汽车音响试音王《金色的草原》24K金碟[低速原抓WAV+CUE][1G]
- 周深 /Faouzia《解密 电影原声带》[320K/MP3][39.32MB]
- 周深 /Faouzia《解密 电影原声带》[FLAC/分轨][199.46MB]
- 英雄联盟s14亚军队伍是哪支 英雄联盟s14亚军队伍介绍
- 英雄联盟s14夺冠队伍是哪支 英雄联盟s14夺冠队SKT T1队伍介绍