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 ...
随机推荐
- python脚本2_输入2个数比较大小后从小到大升序打印
#输入2个数,比较大小后,从小到大升序打印 a = input('first: ') b = input('second: ') if a > b: print(b,a) else: print ...
- Hash算法-CityHash算法
cityhash系列字符串散列算法是由著名的搜索引擎公司Google 发布的 (http://www.cityhash.org.uk/). Google发布的有两种算法:cityhash64 与 ci ...
- 【Python】序列的方法
任何序列都可以引用其中的元素(item). 下面的内建函数(built-in function)可用于列表(表,定值表,字符串) #s为一个序列 len(s) 返回: 序列中包含元素的个数 min(s ...
- 【scala】apply和update
我们在使用scala的时候经常会用到对象的apply方法和update方法. 虽然我们表面没有察觉,但是实际上两个方法都会遵循相关约定被调用. apply apply方法的约定:用括号传递给变量(对象 ...
- C#当中利用Attribute实现简易AOP
首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...
- 一步一步写jQuery插件
转载自:http://www.cnblogs.com/joey0210/p/3408349.html 前言 如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquer ...
- How do I create zip file in Servlet for download?
原文链接:https://kodejava.org/how-do-i-create-zip-file-in-servlet-for-download/ The example below is a s ...
- git配置ssh key并从github.com拉取repos
一.配置ssh key 1. 进入当前用户目录cd ~2. 生成ssh keyssh-keygen -t rsa -C "ABC@qq.com"ABC@qq.com账号必须是你登录 ...
- unity 事件顺序及功能说明
unity3d中所有控制脚本的基类MonoBehaviour有一些虚函数用于绘制中事件的回调,也可以直接理解为事件函数,例如大家都很清楚的Start,Update等函数,以下做个总结. Awake 当 ...
- 余弦相似性计算及python代码实现
A:西米喜欢健身 B:超超不爱健身,喜欢打游戏 step1:分词 A:西米/喜欢/健身 B:超超/不/喜欢/健身,喜欢/打/游戏 step2:列出两个句子的并集 西米/喜欢/健身/超超/不/打/游戏 ...