资讯专栏INFORMATION COLUMN

【generator101】 - yield from

xiaodao / 3095人阅读

摘要:我们可以看一下的可见是由内部支持的,其实现原理上就避免了栈进栈出的消耗,直接由最内层的返回值。另外可以实现外部直接向最内层的传递值,比如这段代码的输出是这样传值的方式,在用循环重新的模式下是无法实现的。这也就是必须使用,而不能使用的原因。

在python 3.3里,generator新增了一个语法 yield from
这个yield from的作用是什么?看下面两段对比的代码:

def zero_to_nine():
    for i in range(10):
        yield i

def wrap_generator():
    for i in zero_to_nine():
        yield i

print(list(zero_to_nine()))
print(list(wrap_generator()))

可以看到一个问题,如果一个函数内部调用了一个generator,它自身如果还希望是以generator的形式返回值的话,就需要用for循环重新yield一次。
使用yield from可以简化这个委托给子generator的过程

def zero_to_nine():
    for i in range(10):
        yield i

def wrap_generator():
    yield from zero_to_nine()

print(list(zero_to_nine()))
print(list(wrap_generator()))

如果只是这么一点写法上的区别的话,也就不劳烦BDFL添加新的语法了。我们可以看一下wrap_generator的bytecode

              0 LOAD_GLOBAL              0 (zero_to_nine) 
              3 CALL_FUNCTION            0 (0 positional, 0 keyword pair) 
              6 GET_ITER             
              7 LOAD_CONST               0 (None) 
             10 YIELD_FROM           
             11 POP_TOP              
             12 LOAD_CONST               0 (None) 
             15 RETURN_VALUE         

可见YIELD FROM是由cPython内部支持的,其实现原理上就避免了栈进栈出的消耗,直接由最内层的frame返回(yield)值。
另外YIELD FROM可以实现外部直接向最内层的generator传递值,比如

def i_yield_whatever_input_is():
    input = None
    while True:
        input = yield input

def wrap_generator():
    yield from i_yield_whatever_input_is()

gen = wrap_generator()
print(gen.send(None))
print(gen.send(1))
print(gen.send(2))
print(gen.send(3))

这段代码的输出是

None
1
2
3

这样send传值的方式,在用for循环重新yield的模式下是无法实现的。这也就是tulip必须使用yield from,而不能使用yield的原因。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37396.html

相关文章

  • generator101】 - 对比generator和greenlet

    摘要:比如里可以直接把执行权交给,而完全不知情。虽然不能和多线程相比,但是效果是类似的。对于多线程的代码,是任何一行代码都可能与其他线程并行。加上协程之间有共享状态的话,一定程度上会产生类似多线程的并发读写状态的。 前面讲generator是显式的协程的时候缺一个例子,现在补上 def parent_generator(): print(hello) yield from ...

    CoyPan 评论0 收藏0
  • generator101】 - pypy的api

    摘要:从到到再到,各家的语法都不太一样。底层的实现是,看名字应该是的意思。然后在这个基础上实现了的和的。的的语法风格也是类似所以从语法上来说就三类这样强制要求的为代表的隐式控制权的为代表强买强卖编码风格的 从generator到greenlet到stackless再到pypy,各家的语法都不太一样。pypy底层的实现是continulet,看名字应该是continuation的意思。然后在这...

    Luosunce 评论0 收藏0
  • generator101】 - generator的输入与输出

    摘要:的是可以有输入输出的,这个特性并不广为人知。也就是要求不返回值,而是抛出给定的异常。执行之后的输出与前面是一样的。 Python的generator是可以有输入输出的,这个特性并不广为人知。这其实是一个挺有用的特性,利用其外部可控制执行进度的特性,再加上可以与外部进行输入输出,generator可以被用来打造成一个异步执行框架,或者说是协程调度引擎。 我们先来看一个最简单的例子,gen...

    melody_lql 评论0 收藏0
  • generator101】 - generator是一种显式控制的协程

    摘要:协程其实就是一个可中途中断,由外部来控制执行进程的函数。这些第三方的选择的共同特点是协程的都是隐式的。这就是显示控制和隐式控制的区别。本文讨论的协程就是这一种,后面会逐渐展开到如何利用这种显示控制的协程来解决阻塞和流程阻塞的问题。 Python官方的实现里,协程只有generator这一招。协程其实就是一个可中途中断,由外部来控制执行进程的函数。除了官方的generator,还有很多第...

    894974231 评论0 收藏0
  • 生成器进化到协程 Part 1

    摘要:生成器用于定义生成器函数只要存在该函数必定是一个生成器调用该函数返回一个生成器让一个生成器前进使用使一个生成器前进到下一个语句处,并将产出值作为其返回值。 前言 这篇文章大部分来自 David Beazley 在 PyCon 2014 的 PPT 《Generators: The Final Frontier》。这个PPT很长而且非常烧脑,建议在阅读前应了解 Python 的生成器与携...

    lemon 评论0 收藏0

发表评论

0条评论

xiaodao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<