send(None)和Next()的区别

16

通过在PEP 342-- 增强生成器的协程中将yield语句重新定义为表达式,Python增加了强大的新功能。David Beasley在Python协程上有一次很好的演讲:关于协程和并发的好奇课程

正如PEP所述,每当生成器通过普通的next()调用恢复时,yield表达式的值都是None。要实例化生成器,必须调用next()或send(None)(即最初不能发送非None值)。

调用next()与send(None)相比是否有任何优势?next()是一个内置函数,因此这可能是一个因素,但似乎没有其他区别。我有些惊讶,这似乎更符合Python的风格,因为向next添加一个可选变量比添加一个执行相同操作的新函数更好。我有什么疏忽吗?

下面是一个简单的协程示例,用于保留输入数字的累加总和,通过将它们发送到协程中实现。

import numbers
def running_sum() :
    g_in  = 0
    g_out = 0
    while g_in is not None :
        g_in = (yield g_out)
        if isinstance(g_in, numbers.Number) :
            g_out += g_in
        print 'in_val =',g_in,'sum =',g_out
1个回答

10
你可能没有意识到的是,生成器是迭代器的一种特殊情况
迭代器是指正确实现了__iter__()__next__()方法的任何对象。 在这种情况下,__iter__()方法只需返回迭代器本身。 而__next__()方法是调用next()的具体实现方法。
然而,关键是__next__()方法不接受除self以外的参数.send()方法不是迭代协议的一部分。 通常情况下,迭代器不需要实现.send()。 实际上,如果你调用iter([]),你会得到一个缺乏该方法的对象。 只有真正的生成器(使用yield语法编写的函数)才支持发送操作。 而next()可以作用于任何迭代器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接