python-yield(yield)有什么作用? [英] python - what does yield (yield) do?

查看:124
本文介绍了python-yield(yield)有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自python 2.5起,就可以将send()throw()close()生成为生成器.在已定义的生成器内部,可以通过执行以下操作来捕获"已发送的数据:

Since python 2.5 there is the ability to send(), throw(), close() into a generator. Inside the defined generator one can 'catch' the sent data by doing something like:

def gen():
    while True:
        x = (yield)
        if x == 3:
            print('received 3!!')
            break
        else:
            yield x

我想玩的是做类似的事情:

What i am trying to play with is doing something like:

def gen2():
    while True:
        yield (yield)

注意到这是做某事的合法生成器. 我要弄清楚的第一件事是:

Noticed that it is a legal generator which does something.. First thing i'm trying to figure out is:

这种写作有很好的用法吗?

在执行类似操作时也是如此:

Also when doing something like:

g = gen2()
next(g)
g.send(10) # output: 10
g.send(2) # output: nothing
g.send(3) # output: 3
g.send(44) # output: nothing

为什么每秒钟的发送"都无济于事?

推荐答案

yield (yield)首先从内部yield产生None.然后,它从sendnext接收一个值.内部yield计算得出该接收到的值,而外部yield迅速产生该值.

yield (yield) first yields None from the inner yield. It then receives a value from send or next. The inner yield evaluates to this received value, and the outer yield promptly yields that value.

每个yield从概念上讲都有两个部分:

Each yield conceptually has two parts:

  1. 将值传送给sendnext的调用方.
  2. 从下一个sendnext调用中接收值.
  1. Transmit a value to the caller of send or next.
  2. Receive a value from the next send or next call.

类似地,每个sendnext在概念上都包含两个部分:

Similarly, each send or next conceptually has two parts:

  1. 向生成器当前暂停的yield表达式传输一个值. (对于next,此值为None.)
  2. 从下一个yield表达式接收一个值.
  1. Transmit a value to the yield expression that the generator is currently paused at. (This value is None for next.)
  2. Receive a value from the next yield expression.

系统中最混乱的部分可能是这些部分错开了. yield的两个部分对应于sendnext的两个不同的调用,而sendnext的两个部分对应于两个不同的yield的调用.

The most confusing part of the system is probably that these parts are staggered. The two parts of a yield correspond to two different invocations of send or next, and the two parts of a send or next correspond to two different yields.

如果我们通过一个简单的示例进行操作:

def gen():
    print('Not ran at first')
    yield (yield)

g = gen()  # Step 1
print(next(g))  # Step 2
print(g.send(1)  # Step 3
g.send(2)  # Step 4

这是工作原理:

Inside the generator                      Outside the generator

第1步

                                          g calls gen()
g returns a generator object 
without executing the print
just yet statement.
                                          >>> g
                                          <generator object gen at 0x7efe286d54f8>

第2步

                                          next(g) sends None to g
g receives None, ignores it
  (since it is paused at the start
   of the function)

g prints ('not ran at first')

g executes the "transmit" phase
  of the inner yield, transmitting
  None
                                          next(g) receives None

第3步

                                          g.send(1) sends 1 to g
g executes the "receive" phase
  of the inner yield, receiving 1
g executes the "transmit" phase
  of the outer yield, transmitting 1
                                          g.send(1) receives 1 from g

第4步

                                          g.send(2) sends 2 to g
g executes the "receive" phase
  of the outer yield, receiving 2
g reaches the end of gen and raises
  a StopIteration
                                          g.send(2) raises the StopIteration
                                          from g

这篇关于python-yield(yield)有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆