Python生成器next方法和send方法区别

生成器简介

python中,含有yield关键字的对象就是一个生成器,每次调用next方法时会执行到yield后面的语句,而后返回yield后面代码块的执行结果。其实也能够调用send方法
下面给个例子方便理解。html

next方法

def foo():
    bar_a = yield 1         # bar_a是语句块(yield 1)的返回值,默认为None
    bar_b = yield bar_a
    yield "最后一个值,再迭代就要报StopIteration了"

f = foo()                   # 建立生成器,此时没有执行foo()里的任何语句
print(next(f))              # 从foo()里进入,一直执行到(yield 1)处,此时变量bar_a尚未建立
print(next(f))              # 先将语句块(yield 1)的返回值赋值个bar_a,此时bar_a的值是None。
                            # 而后执行到语句块(yield bar_a),bar_b也尚未被建立
print(next(f)

输出:python

>>>1
>>>None
>>>最后一个值,再迭代就要报StopIteration了

能够看出,f = foo()建立生成器时,每次执行到yield时,会跳出去并将yield关键字后面的内容返回给调用者。下一次有别的调用者再次调用生成器时,会先恢复生成器上次的机器状态,再接着执行指导遇到yield或者元素迭代完毕。
并且咱们能够看到bar_abar_b是语句yield 1yield bar_a的返回值,注意:不是生成器的返回值
这里有个比较绕的地方,咱们用bar_a = yield 1作分析:express

  • 1是生成器的返回值。由于生成器返回yield后面的代码块
  • bar_a是语句yield 1的返回值,这就比如咱们写函数

    a = print('my lover')
    print('a的值是:', a)

    会输出:翻译

    >>>my lover
    >>>a的值是: None

send方法

def foo():
    bar_a = yield 1
    bar_b = yield bar_a
    yield "最后一个值,再迭代就要报StopIteration了"

f = foo()
print(f.send(None))
print(f.send("my lover"))
print(next(f))

输出:code

>>>1
>>>my lover
>>>最后一个值,再迭代就要报StopIteration了

这里f.send(None)是初始化生成器,和next(f)的效果如出一辙。可是不推荐这么写,由于不规范。
注意输出的第二行是字符串my lover,而不是None。这是由于send函数带有一个参数,这个参数会覆盖yield 1语句的返回值,也就是bar_a的值如今不是None了。htm

FAQ

官网提到,当咱们建立一个生成器时,第一次调用只能用next()或者send(None)。由于此时send传入其余参数也没有yield语句去接收。
这句话我看不懂,说的好像传入None就有yield来接收似的。各位若是明白的欢迎指点。
原文和传送门以下:对象

官网传送门字符串

Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.
Google翻译版本:
恢复执行并将值“发送”到生成器函数中。所述 值参数成为当前产量表达的结果。该 send()方法返回由生成器产生的下一个值,或者StopIteration若是生成器退出而不产生另外一个值则引起。当send()调用启动生成器时,必须将其None做为参数调用,由于没有能够接收该值的yield表达式。

更新:
2018-11-24
对生成器使用send(None)方法,解释器在底层会调用__next__方法,也就是next()方法get

相关文章
相关标签/搜索