Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3:生成器的发送方法_Python_Python 3.x_Generator - Fatal编程技术网

Python 3:生成器的发送方法

Python 3:生成器的发送方法,python,python-3.x,generator,Python,Python 3.x,Generator,我无法理解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 = ge

我无法理解
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\u list
    的值被返回给
    next
    的调用者。 嗯,这似乎没有发生。为什么我们可以在
    gen()
    中执行
    if
    语句和
    print
    函数
  • 我如何理解函数内部和外部不同的原因? 好啊让我们假设
    send(77)
    将77传输到
    m
    。嗯,
    yield
    表达式变成77。 那么什么是
    X=yield i
    ?当函数外部发生时,函数内部的77如何转换为5
  • 为什么第一个结果字符串不反映生成器中发生的任何事情

  • 无论如何,你能对这些
    send
    yield
    语句发表评论吗?

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

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

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

    作为隐喻,考虑A:

    当服务员收到顾客的订单时,他们把便笺簿放在哑侍者的肚子里,
    把它送到厨房,然后在舱口等菜:

    R = kitchen.send("Ham omelette, side salad")
    
    厨师(一直在舱口旁等待)拿起订单,准备菜肴,
    yield
    s将其送到餐厅,然后等待下一个订单:

    next_order = yield [HamOmelette(), SideSalad()]
    
    服务员(一直在舱口等着)把盘子拿给顾客,然后带着另一份订单回来,等等

    因为在
    发送一份订单或
    下一道菜后,服务员和厨师都会在舱口等待,所以在任何时候只有一个人在做任何事情,即该过程是单线程的。双方都可以使用正常的控制流,因为生成器机器(哑侍者)负责交错执行

    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=收益率I”陈述, 这句话并不是说从send()方法接受的值被关联到i,然后我被关联到x。
    相反,值i由yield station返回给生成器,x由send()方法生成。一条语句同时做两件事。

    最容易混淆的部分应该是这一行
    x=yield i
    ,特别是在生成器上调用
    send()
    时。实际上,你唯一需要知道的是:

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

    在口译员级别:
    X=收益率i
    等于以下几行(订单事项):


    和2条注释是确切的原因,为什么我们需要第一次调用<代码>发送(没有)>代码>,因为生成器会返回<代码> i>代码(屈服<代码> i>代码> <强> < < /强> >将值分配给<代码> x< /代码>

    ,因为您甚至征求意见,请考虑以下情况:

    def lambda_maker():
        def generator():
            value = None
            while 1:
                value = yield value
                value= value[0][1]
        f = generator()
        next(f)  # skip the first None
        return f.send  # a handy lambda value: value[0][1]
    
    现在,以下两行是等效的:

    a_list.sort(key=lambda a: a[0][1])
    a_list.sort(key=lambda_maker())
    
    (顺便提一下,在当前(2018-05-26,GDPR后第1天)☺) 在CPython2和CPython3实现中,第二行比第一行运行得更快,但这是与每次函数调用的帧对象初始化开销相关的细节。)

    这里发生了什么?
    lambda\u maker
    调用
    f=generator()
    并获取一个生成器;调用初始值
    next(f)
    开始运行生成器并使用初始的
    None
    值,并在
    yield
    行暂停。然后它将绑定方法
    f.send
    返回给调用方。从这一点开始,每次调用此绑定方法时,
    generator.value
    local都会收到绑定方法的参数recalculates
    value
    然后循环返回
    yield
    ing
    value
    的当前值,并等待下一个
    。send
    获取另一个值

    生成器对象保留在内存中,它在循环中所做的一切是:

    • 产生当前结果(最初无)
    • 接收另一个值(任何人用作
      .send
      参数的值)
    • 根据接收到的值重新计算当前结果
    • 回环
      • 注意:
        为了简单起见,我的回答仅限于生成器每行最多有1个
        yield
        命令的情况

        TL;DR:

        • .send()
          方法:

          • 将值发送到当前挂起的命令,但<
            a_list.sort(key=lambda a: a[0][1])
            a_list.sort(key=lambda_maker())
            
            received_1 = yield "first_from_iterator"      
            
            result = math.cos((yield "first_from_iterator") * math.pi)         # result: -1
            
            g.send(1)                          # Not very appropriate
            
            from_iterator_2 = g.send(1)        # Saving the 2nd yielded value