Python 3:生成器的发送方法 [英] Python 3: send method of generators

查看:111
本文介绍了Python 3:生成器的发送方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听不懂send方法.我了解它用于操作发电机.但 语法在这里:generator.send(value).

I can't understand the send method. I understand that it is used to operate the generator. But the syntax is here: generator.send(value).

我不知为何无法理解为什么该值应成为当前yield表达式的结果.我准备了一个例子:

I somehow can't catch why the value should become the result of the current yield expression. I prepared an example:

def gen():
    for i in range(10):
        X = yield i
        if X == 'stop':
            break
        print("Inside the function " + str(X))

m = gen()
print("1 Outside the function " + str(next(m)) + '\n')
print("2 Outside the function " + str(next(m)) + '\n')
print("3 Outside the function " + str(next(m)) + '\n')
print("4 Outside the function " + str(next(m)) + '\n')
print('\n')
print("Outside the function " + str(m.send(None)) + '\n') # Start generator
print("Outside the function " + str(m.send(77)) + '\n')
print("Outside the function " + str(m.send(88)) + '\n')
#print("Outside the function " + str(m.send('stop')) + '\n')
print("Outside the function " + str(m.send(99)) + '\n')
print("Outside the function " + str(m.send(None)) + '\n')

结果是:

1 Outside the function 0

Inside the function None
2 Outside the function 1

Inside the function None
3 Outside the function 2

Inside the function None
4 Outside the function 3



Inside the function None
Outside the function 4

Inside the function 77
Outside the function 5

Inside the function 88
Outside the function 6

Inside the function 99
Outside the function 7

Inside the function None
Outside the function 8

坦率地说,这让我感到惊讶.

Well, frankly speaking, it is astonishing me.

  1. 在文档中我们可以看到,执行yield语句时,生成器的状态被冻结,并且expression_list的值返回给next的调用方. 好吧,这似乎没有发生.为什么我们要在gen()中执行if语句和print函数.
  2. 我如何理解功能内外的X为什么不同? 好的.让我们假设send(77)将77传输到m中.好吧,yield表达式变成77. 那么X = yield i是什么?而函数内部的77如何在外部发生时转换为5?
  3. 为什么第一个结果字符串不能反映生成器内部发生的任何事情?
  1. In the documentation we can read that when a yield statement is executed, the state of the generator is frozen and the value of expression_list is returned to next‘s caller. Well, it doesn't seem to have happened. Why can we execute if statement and print function inside gen().
  2. How can I understand why X inside and outside the function differs? Ok. Let us assume that send(77) transmits 77 into m. Well, yield expression becomes 77. Then what is X = yield i? And how 77 inside the function converts into 5 when occurs outside?
  3. Why the first result string doesn't reflect anything that is going on inside the generator?

无论如何,您能以某种方式对这些sendyield语句发表评论吗?

Anyway, could you somehow comment on these send and yield statements?

推荐答案

在生成器中使用send和表达式yield时,会将其视为协程.一个单独的执行线程,可以按顺序交错运行,但不能与其调用者并行运行.

When you use send and expression yield in a generator, you're treating it as a coroutine; a separate thread of execution that can run sequentially interleaved but not in parallel with its caller.

当调用者执行R = m.send(a)时,它将对象a放入生成器的输入插槽中,将控制权移交给生成器,然后等待响应.生成器将接收对象a作为X = yield i的结果,并运行直到遇到另一个yield表达式,例如Y = yield j.然后,它将j放入其输出插槽,将控制权转回调用方,并等待直到再次恢复.调用方收到j作为R = m.send(a)的结果,并一直运行直到命中另一个S = m.send(b)语句,依此类推.

When the caller executes R = m.send(a), it puts the object a into the generator's input slot, transfers control to the generator, and waits for a response. The generator receives object a as the result of X = yield i, and runs until it hits another yield expression e.g. Y = yield j. Then it puts j into its output slot, transfers control back to the caller, and waits until it gets resumed again. The caller receives j as the result of R = m.send(a), and runs until it hits another S = m.send(b) statement, and so on.

R = next(m)R = m.send(None)相同;它将None放入生成器的输入插槽中,因此,如果生成器检查X = yield i的结果,则X将为None.

R = next(m) is just the same as R = m.send(None); it's putting None into the generator's input slot, so if the generator checks the result of X = yield i then X will be None.

作为一个比喻,考虑使用哑巴服务员:

As a metaphor, consider a dumb waiter:

当服务器从客户那里收到订单时,他们将垫子放在笨拙的服务员中,send放到厨房,然后在舱口旁等待菜品:

When the server gets an order from a customer, they put the pad in the dumb waiter, send it to the kitchen, and wait by the hatch for the dish:

R = kitchen.send("Ham omelette, side salad")

厨师(一直在舱口旁等待)拿起订单,准备菜肴,yield将其送到餐厅,然后等待下一个订单:

The chef (who's been waiting by the hatch) picks up the order, prepares the dish, yields it to the restaurant, and waits for the next order:

next_order = yield [HamOmelette(), SideSalad()]

服务器(一直在舱口旁等待)将菜带给客户,然后再下单,以此类推.

The server (who's been waiting by the hatch) takes the dish to the customer and returns with another order, etc.

由于服务器和厨师都在send下达订单或yield下完菜后在舱口旁等待,所以任何时候只有一个人在做任何事情,即该过程是单线程的.双方都可以使用正常的控制流,因为发电机机械(哑服务员)负责交错执行.

Because both the server and chef wait by the hatch after sending an order or yielding a dish, there's only one person doing anything at any one time i.e. the process is single threaded. Both sides can use normal control flow, as the generator machinery (the dumb waiter) takes care of interleaving execution.

这篇关于Python 3:生成器的发送方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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