Python 3:发送器的发送方法

我无法理解send方法。 我知道它是用来操作发生器的。 但语法如下: generator.send(value)

我不知道为什么价值应该成为当前yield表达式的结果。 我准备了一个例子:

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

坦率地说,这让我很惊讶。

  • 在文档中我们可以看到,当yield语句被执行时,生成器的状态被冻结,并且expression_list的值被返回给next调用者。 好吧,它似乎并没有发生。 为什么我们可以执行if语句并print内部功能gen()
  • 我怎么理解为什么函数内外的X区别? 好。 让我们假设send(77)发送给m 。 那么, yield表达式变成77.那么X = yield i什么? 当外部发生时,函数内部的77如何转换为5?
  • 为什么第一个结果字符串不能反映生成器内部发生的任何事情?
  • 无论如何,你能否以某种方式评论这些sendyield声明?


    当你在发生器中使用send和表达式yield时,你将它视为协程; 一个独立的执行线程,可以顺序交错但不与其调用者并行运行。

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

    R = next(m)R = m.send(None) ; 它将None放入发生器的输入槽,所以如果发生器检查X = yield i的结果,那么X将是None

    作为一个比喻,考虑一个愚蠢的服务员:

    愚蠢的服务员

    当服务员接到客户的订单时,他们把垫放在哑巴服务员的手中, send它送到厨房,然后在舱口等候这道菜:

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

    厨师(谁一直在等待通过舱口)拿起顺序,准备的菜, yield是S到餐厅,并等待下一个命令:

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

    服务器(已经在舱口等待)将餐具拿到顾客处,并用另一个订单返回等等。

    因为服务员和厨师在send订单或yield一道菜后等待孵化器,所以只有一个人在任何时间做任何事情,即该过程是单线程的。 双方都可以使用正常的控制流程,因为发电机组(愚蠢的服务员)负责交错执行。


    最令人困惑的部分应该是这行X = yield i ,特别是当你在发生器上调用send()时。 其实你唯一需要知道的是:

    在词汇层次上: next()等于send(None)

    在解释者层面: X = yield i等于线下( 订货物 ):

    yield i
    # won't continue until next() or send() is called
    # and this is also the entry point of next() or send()
    X = the_input_of_send
    

    并且,这两行注释是确切的原因,为什么我们需要第一次调用send(None) ,因为生成器会将值赋给X 之前返回i (yield i


    def gen():
        i = 1
        while True:
            i += 1
            x = yield i
            print(x)
    
    m = gen()
    next(m)
    next(m)
    m.send(4)
    

    结果

    None
    4
    

    看看上面更简化的代码。
    我认为引起你的困惑的事情是'x = yield i'的表述,这个表述并不是说从send()方法接受的值被分配给了我,然后我被分配给了x。 相反,价值我通过yield statment返回到生成器,x通过send()方法来分裂。一个语句同时做两件事。

    链接地址: http://www.djcxy.com/p/79383.html

    上一篇: Python 3: send method of generators

    下一篇: Coordinating parallel execution in node.js