yield from

参考:http://aju.space/2017/07/31/Drive-into-python-asyncio-programming-part-1.html

yield from  是Python 3.3 新引入的语法(PEP 380)。

它主要解决的就是在生成器里玩生成器不方便的问题。它有两大主要功能;

第一个功能是:让嵌套生成器不必通过循环迭代yield,而是直接yield from

以下两种在生成器里玩子生成器的方式是等价的:

# 方式一:使用 yield
def gen_two():
    subgen = (i**2 for i in range(2,5))
    for item in subgen:
        yield item

b = gen_two()
print(type(b),b)
for j in b:
    print(j)

# 方式二:使用 yield from
def gen_one():
    subgen = (i**2 for i in range(2,5))
    yield from subgen

a = gen_one()
print(type(a),a)
for i in a:
    print(i)

  

第二个功能:在子生成器和原生成器的调用者之间打开双向通道,两者可以直接通信。

def gen():
    yield from subgen()
    print("end gen...")

def subgen():
    try:
        while True:
            x = yield
            yield x+1
    except Exception as e:
        print("StopIteration in subgen...")

if __name__ == ‘__main__‘:
    g = gen()
    g.send(None)                # 驱动生成器g开始执行到第一个 yield
    retval = g.send(1)          # 看似向生成器 gen() 发送数据
    print(retval)               # 返回2
    g.throw(StopIteration)      # 看似向gen()抛入异常

### 结果 ###
2
StopIteration in subgen...
end gen...
Traceback (most recent call last):
  File "D:/soft/work/Python_17/day25/async_IO/xxx.py", line 75, in <module>
    g.throw(StopIteration)      # 看似向gen()抛入异常
StopIteration

  

关键字yield from在gen()内部为subgen()和main()开辟了通信通道。

main()里可以直接将数据1发送给subgen(),
subgen()也可以将计算后的数据2返回到main()里;

main()里也可以直接向subgen()抛入异常以终止subgen()。

顺带一提:
yield from 除了可以 yield from <generator> 还可以 yield from <iterable>。

  

时间: 2024-10-13 12:37:29

yield from的相关文章

关于Python中的yield

关于Python中的yield http://www.cnblogs.com/tqsummer/archive/2010/12/27/1917927.html http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议

ruby yield 关键字用法实例

yield关键字我是这样理解,用它来占一个位置,先标记下这个地方将来要写代码的,等到调用的时候,再来编写具体的代码.有点像函数指针,或者C#里的委托,但其实并不太一样. 写测试接口的时候,每次的assert返回值不一样,但函数体大部分是相同的,只有参数不同.正好最近看到了yield,就熟悉一下用法,可以把assert这部分code写在yield 的位置. 例子主要就是test_nodes这个函数的定义 和 它的调用. Code: 1 def generate_nodes(n=3) 2 retur

lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

问题 attempt to yield across metamethod/C-call boundary 需求跟如下帖子中描述一致: http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=4065715 模拟一个场景,在C中创建出coroutine来执行Lua脚本,并且提供C API给Lua使用,当某些操作可能会阻塞时(如网络I/O),C函数中执行yield将协程切换出去,然后未来的某个时刻,如果条件

yield生成器及字符串的格式化

一.生成器 1 def ran(): 2 print('Hello world') 3 yield 'F1' 4 5 print('Hey there!') 6 yield 'F2' 7 8 print('goodbye') 9 yield 'F3' 10 11 ret = ran() # ran()称为生成器函数,ret才是生成器,仅仅具有一种生成能力,函数内部要有关键字yield 12 print(ret) 13 14 res = ret.__next__() #对生成器进行循环操作,遇到y

利用 Python yield 创建协程将异步编程同步化

在 Lua 和 Python 等脚本语言中,经常提到一个概念: 协程.也经常会有同学对协程的概念及其作用比较疑惑,本文今天就来探讨下协程的前世今生. 首先回答一个大家最关心的问题:协程的好处是什么? 通俗易懂的回答: 让原来要使用 异步 + 回调 方式写的非人类代码,可以用看似同步的方式写出来. 1.回顾同步与异步编程 同步编程即线性化编程,代码按照既定顺序执行,上一条语句执行完才会执行下一条,否则就一直等在那里. 但是许多实际操作都是CPU 密集型任务和 IO 密集型任务,比如网络请求,此时不

sleep、yield和join

(1)sleep和yield都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,但两者的区别在于: sleep给其它线程运行的机会,但不考虑其它线程的优先级:但yield只会让位给相同或更高优先级的线程: 当线程执行了sleep方法后,将转到阻塞状态,而执行了yield方法之后,则转到就绪状态: sleep方法有可能抛出异常,而yield则没有: 在一般情况下,我们更建议使用sleep方法. (2)join方法用于等待其它线程结束,当前运行的线程可以调用另一线程的join方法,

python yield

http://www.jb51.net/article/15717.htm  这里还不错 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def addlist(alist):    for i in alist:        yield i + 1 取出alist的每一项,然后把i + 1塞进去.然后通过调用取出每一项: alist = [1, 2, 3, 4]for x in addlist(alist):    print x, 这的确是yield应用的一个例子

php5.5新特性之yield理解

今天,在阅读别人代码时,其中出现了一个陌生的关键字yield,想一探究竟,于是找到:http://php.net/manual/zh/language.generators.overview.php yield生成器是php5.5之后出现的,yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低. yield生成器允许你 在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组. 使用示例: /** *

C# yield return用法

本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解.具体如下: yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: ? 1 2 3 4 static List<int> GetInitialData() {   return new List<int>(){

python学习第十节(yield表达式的应用+内置函数)

上节复习 yield表达式g.send(1)send函数是相当于next并且给yield传一个值,先传值,再next 加上装饰器 yield表达式的应用 第一个是当前目录的地址第二个是当前目录下的目录第三个是当前目录下的文件再次next(g)就可以查看当前目录下第一个目录下的信息 ##############下面是更改版本##################### 内置函数all() 所有为true才为trueany() 只要有true 就为truebin()十进制转为2进制oct()十进制转为