zoukankan      html  css  js  c++  java
  • Python的生成器send()方法 & yield_from

    生成器对象是一个迭代器。但是它比迭代器对象多了一些方法,它们包括send方法,throw方法和close方法。这些方法,主要是用于外部与生成器对象的交互。本文先介绍send方法。

    send

    send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。这样说起来比较抽象,看下面的例子。

    def MyGenerator():
    value = (yield 1)
    value = (yield value)
    
    
    gen = MyGenerator()
    print (next(gen))
    print gen.send(2)
    print gen.send(3)
    输出的结果如下
    1
    2
    Traceback (most recent call last): File "test.py", line 18, in <module> print gen.send(3) StopIteration

    上面代码的运行过程如下。
    当调用gen.next()方法时,python首先会执行MyGenerator方法的yield 1语句。由于是一个yield语句,因此方法的执行过程被挂起,而next方法返回值为yield关键字后面表达式的值,即为1。

    当调用gen.send(2)方法时,python首先恢复MyGenerator方法的运行环境。同时,将表达式(yield 1)的返回值定义为send方法参数的值,即为2。这样,接下来value=(yield 1)这一赋值语句会将value的值置为2。继续运行会遇到yield value语句。因此,MyGenerator方法再次被挂起。同时,send方法的返回值为yield关键字后面表达式的值,也即value的值,为2。

    当调用send(3)方法时MyGenerator方法的运行环境。同时,将表达式(yield value)的返回值定义为send方法参数的值,即为3。这样,接下来value=(yield value)这一赋值语句会将value的值置为3。继续运行,MyGenerator方法执行完毕,故而抛出StopIteration异常。

    注意一个要点:生成器函数在运行时候遇到yield时候就会挂起来,不会往下继续运行,直到有人调用.next()或者send()才会将值抛出然后往下运行。

    总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。例如

    gen = MyGenerator()
    print gen.send(2)
    
    上面代码的输出为
    Traceback (most recent call last):
    File "test.py", line 16, in <module>
    print gen.send(2)
    TypeError: can't send non-None value to a just-started generator

    当然,下面的代码是可以接受的

    gen = MyGenerator()
    print gen.send(None)

    因为当send方法的参数为None时,它与next方法完全等价。但是注意,虽然上面的代码可以接受,但是不规范。所以,在调用send方法之前,还是先调用一次next方法为好。

    yield from (功能十分强大)

      yield from 后面必须接一个iterable对象。

    def gen_list(list):
        yield from list
    
    d = gen_list(['frank', 'yangchao', 'liuliu'])
    for i in d:
        print(i)
    
    frank
    yangchao
    liuliu

      yield与yield from()的区别如下:yield from 可以将可迭代对象中的每个对象迭代出来。

    def yield_func(iterable):
        yield iterable
    def yield_from_func(iterable):
        yield from iterable
    
    yield_gen = yield_func(range(10))
    for i in yield_gen:
        print(i)
    yield_from_gen = yield_from_func(range(10))
    for i in yield_from_gen:
        print(i)
    
    range(0, 10)
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
  • 相关阅读:
    移动端 video播放器层级过高,遮挡住其他内容
    页面多个H5播放器video,如何点击当前视频其他视频暂停
    h5页面在移动端禁止缩放,双击放大,双指放大
    uni-app发h5本地浏览index.html空白的问题
    运行nvue 页面报错reportJSException >>>> exception function:GraphicActionAddElement, exception:You are trying to add a u-text to a u-text, which is illegal as u-text is not a container
    nvue页面注意事项
    移动端可能遇到的问题解决方案
    将博客搬至CSDN
    安装node后配置在全局配置
    swiper使用loop后,无法获取索引的问题
  • 原文地址:https://www.cnblogs.com/yc3110/p/10466039.html
Copyright © 2011-2022 走看看