yield-from示例
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2018/6/20 9:13
# @File : yield_from11.py
from collections import namedtuple
Result = namedtuple('Result', 'count average')
# 子生成器
def averager():
total = 0.0
count = 0
average = None
while True:
# main 函数发送数据到这里
term = yield
if term is None: # 终止条件
break
total += term
count += 1
average = total / count
return Result(count, average) # 返回的Result 会成为grouper函数中yield from表达式的值
# 委派生成器
def grouper(results, key):
# 这个循环每次都会新建一个averager实例,每个实例都是作为协程使用的生成器对象
while True:
# grouper 发送的每个值都会经由yield from 处理,通过管道传给 averager
# grouper 会在yield from表达式处暂停,等待 averager 实例处理客户端发来的值。
# averager 实例运行完毕后,返回的值绑定到results[key] 上。
# while 循环会不断创建 averager 实例,处理更多的值。
results[key] = yield from averager()
# 调用方
def main(data):
results = {}
for key, values in data.items():
# group 是调用grouper函数得到的生成器对象,传给grouper 函数的第一个参数是results,用于收集结果;第二个是某个键
group = grouper(results, key)
next(group)
for value in values:
# 把各个value传给grouper 传入的值最终到达averager函数中
# grouper并不知道传入的是什么,同时grouper实例在yield from处暂停
group.send(value)
# 把None传入groupper,传入的值最终到达averager函数中,导致当前实例终止。然后继续创建下一个实例。
# 如果没有group.send(None),那么averager子生成器永远不会终止,委派生成器也永远不会在此激活,也就不会为result[key]赋值
group.send(None)
report(results)
# 输出报告
def report(results):
for key, result in sorted(results.items()):
group, unit = key.split(';')
# print('{:2} {:5} averaging {:.2f}{}'.format(result.count, group, result.average, unit))
print('{:2} {:5} averaging {:.2f}{}'.format(result.count, group, result.average, unit))
# print(result, type(result)) # Result(count=6, average=54.0) <class '__main__.Result'>
data = {
'girls;kg': [40, 41, 42, 43, 44, 54],
'girls;m': [1.5, 1.6, 1.8, 1.5, 1.45, 1.6],
'boys;kg': [50, 51, 62, 53, 54, 54],
'boys;m': [1.6, 1.8, 1.8, 1.7, 1.55, 1.6],
}
if __name__ == '__main__':
main(data)
'''
这段代码从一个字典中读取男生和女生的身高和体重。然后把数据传给之前定义的 averager 协程,最后生成一个报告。
执行结果为
6 boys averaging 54.00kg
6 boys averaging 1.68m
6 girls averaging 44.00kg
6 girls averaging 1.58m
这断代码展示了yield from 结构最简单的用法。委派生成器相当于管道,所以可以把任意数量的委派生成器连接在一起---一个委派生成器使用yield from 调用一个子生成器,
而那个子生成器本身也是委派生成器,使用yield from调用另一个生成器。最终以一个只是用yield表达式的生成器(或者任意可迭代对象)结束。
'''
yield from 的意义
PEP380 分6点说明了yield from 的行为。
子生成器产出的值都直接传给委派生成器的调用方(客户端代码)
使用send() 方法发给委派生成器的值都直接传给子生成器。如果发送的值是None,那么会调用子生成器的 __next__()方法。如果发送的值不是None,那么会调用子生成器的send()方法。如果调用的方法抛出StopIteration异常,那么委派生成器恢复运行。任何其他异常都会向上冒泡,传给委派生成器。
生成器退出时,生成器(或子生成器)中的return expr 表达式会触发 StopIteration(expr) 异常抛出。
yield from表达式的值是子生成器终止时传给StopIteration异常的第一个参数。
传入委派生成器的异常,除了 GeneratorExit 之外都传给子生成器的throw()方法。如果调用throw()方法时抛出 StopIteration 异常,委派生成器恢复运行。StopIteration之外的异常会向上冒泡。传给委派生成器。
如果把 GeneratorExit 异常传入委派生成器,或者在委派生成器上调用close() 方法,那么在子生成器上调用close() 方法,如果他有的话。如果调用close() 方法导致异常抛出,那么异常会向上冒泡,传给委派生成器;否则,委派生成器抛出 GeneratorExit 异常。
yield-from示例的更多相关文章
- python yield 使用示例
1.yield由于创建迭代器 def deal(): tmp = [] for i in range(20): tmp.append(i) if i % 4 == 0: yield tmp tmp = ...
- PHP生成器yield使用示例
<?php function getLines($file) { $f = fopen($file, 'r'); try { while ($line = fgets($f)) { yield ...
- 第十三天python3 生成器yield
生成器generator 生成器指的是生成器对象,可由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象: 生成器函数 函数体中包含yield语句的函数,返 ...
- python基础-迭代器和生成器
一.递归和迭代 1.递归:(问路示例) 递归算法是一种直接或者间接地调用自身算法的过程.在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解. 2.迭代:简单理 ...
- ylbtech-LanguageSamples-Yield
ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Yield 1.A,示例(Sample) 返回顶部 “Yield”示例 本示例演示如何创 ...
- Scala入门 【1】
Scala入门 [1] 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 基础 val定义的为常量,var为变量 val name:Type = ***,变量名后加冒号 ...
- python系列之 - 并发编程(进程池,线程池,协程)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Generator和Coroutine学习
简单的生产者消费者模型 #!/usr/bin/python2.7 def consumer(): while True: newn = yield print 'Consumer : {}'.form ...
- python并发编程之进程池,线程池,协程
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Scala详解
1 快速入门... 4 1.1 分号... 4 1.2 常变量声明... 4 1.2.1 val常量... 4 1.2.2 ...
随机推荐
- IOS-社会化分享
一.如何实现社交分享 在iOS中,实现“社交分享”的方法 1.自己编写各个平台的分享代码(代码量较多) 2.利用iOS自带的Social.framework 3.利用第三方的分享框架 友盟分享 ...
- HAWQ取代传统数仓实践(十六)——事实表技术之迟到的事实
一.迟到的事实简介 数据仓库通常建立于一种理想的假设情况下,这就是数据仓库的度量(事实记录)与度量的环境(维度记录)同时出现在数据仓库中.当同时拥有事实记录和正确的当前维度行时,就能够从容地首先维护维 ...
- OpenCV获取RTSP解码播放
#include <opencv2/opencv.hpp> int main(int argc, char **argv){ IplImage *pFrame = NULL, *srcIm ...
- 旧书重温:0day2【4】动态获取函数地址
通过以上3篇文章的学习,我们已经可以获取到kernel32.dll的地址了下一步 我们就是获取几个重要的函数 1.GetProcAddress 2.LoadLibrary 有了这两个函数很多函数都可以 ...
- 微信小程序-富文本解析插件wxParse基础使用及问题解决
一.插件准备 在github上可以直接下载该插件:https://github.com/icindy/wxParse 二.基本使用 1.将插件导入项目: 将wxParse文件夹放在项目目录下,如图: ...
- LINUX (centos)设置IP地址,网关,DNS
首先:备份原始配置文件: [logonmy@logon ~]$ cd /etc/sysconfig/network-scripts/ [logon@logon network-scripts]$ pw ...
- ranch实现游戏服务器
在 erlang游戏开发tcp 我们建立起了自己的socket tcp 服务器的基本骨架.当时面对并发情况下,多人同一时刻连接服务器的时候,我们的基本骨架 还是难以应付处理.这就使我不得不想对这样的情 ...
- 为什么要编写轻量级的View Controller??
1.作为iOS项目中最大的文件,ViewControllers中的代码复用率几乎是最低的2.重量级的View COntroller加大了测试的复杂度.所以关注ViewController的瘦身,把业务 ...
- 51nod 1089 最长回文子串 V2(Manacher算法)
回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. 收起 输入 输入Str(Str的长度 <= 100000) ...
- 在IIS站点中使用数字证书
1. SSL解析(内容来自百度百科) SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安 ...