b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

异步编程之使用 yield from

电脑杂谈  发布时间:2019-08-23 16:01:48  来源:网络整理

c#异步编程_c 异步编程_task异步编程

异步编程之使用 yield from

yield from 是 Python3.3 后新加的语言构架。yield from 的主要功用是开启单向通道,把最外层的读取方式与最表层的子生成器连接起来。这两者就可以进行发送值和返回值了,yeild from 结构的本质是简化嵌套的制造器,不理解这个是什么含义的话,下面我将用几个例子来对其使用方式进行讲解。

首先看一个

def gene():
    for c in 'AB':
        yield c  #遇到 yeild 程序返回循环,下次从 yeild 后面开始。
    for i in range(3):
        yield i 
if __name__=="__main__":
    list(gene())#list 内部会预激

输出

task异步编程_c#异步编程_c 异步编程

['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 中如若重复的代码出现了两次以及以下就要考量优化了。好了接下来我们看一个优化后的举例。

c 异步编程_task异步编程_c#异步编程

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 源码地址 )

# 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)

c#异步编程_c 异步编程_task异步编程

接下来通过说一下开篇讲到的子生产器和调用方以及新的词委托。

yield from x 表达式对 x 对象做的第一件事是,调用 iter(x),从中获取一个迭代器。所以 x 是可迭代对象。上面的举例中的 x 如果是可迭代对象就会执行,yield from flatten(x).

PEP380 的标题是 ” syntax for delegating to subgenerator “(把指责委托给子生成.器的语义)。由此我们可以清楚,yield from 是可以实现嵌套的使用。

yield from 在看接下来的代码之前我们应该明白这几个概念:

包含 yield from <iterable> 表达式的函数</iterable>

task异步编程_c#异步编程_c 异步编程

从 yield from <iterable> 部分获取的,含义 yield 的。</iterable>

调用委派的客户端(调用方)代码,也就是运行入口。

ok,了解了很多我们看接下来的一个例子。

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 处理c 异步编程,然后传给 fetch 实例。url_list 会在 yield from 表达式处暂停,等待 fetch 实例处理客户端发来的值。fetch 实例运行完毕后,返回的值绑定到 l[key] 上。while 循环会不断创建 fetch 实例,处理更多的值。⑧激活 url_list ⑨把各个 url 以及其序列号 indexc 异步编程,传给 url_list 传入的值最终到达 fetch 函数中,url_list 并不知道传入的是什么,同时 url_list 实例在 yield from 处暂停。直到 fetch 的一个实例处理完才进行异或。⑩关键的一步,ul 把 None 传入 url_list,传入的值最后到达 fetch 函数中,导致当前示例终止。然后继续建立下一个实例。如果没有 ul.send(None),那么 fetch 子永远不会终止,因为 ul.send()发送的值实际是在 fetch 实例中进行,委派也永远不会在此激活,也就不会为 l[key]赋值

流畅的 python 第 16 章PEP 380-- Syntax for Delegating to a SubgeneratorHow Python 3.3 "yield from" construct works


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-120304-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...