在此示例中使用 "yield" 的正确方法

The proper way of using "yield" in this example

我正在尝试演示如何使用 Python 中的 yield。我想通过一个例子来证明这一点。

该示例将要求用户输入 yesno,并在每次输入 yes 时将计数器 n 加 1。

我想展示 yield 如何工作的部分是当用户再次调用该函数时,并获得更新的次数值。例如,如果使用 return,用户再次运行该脚本,它将从头开始,次数为 1。相反,我希望用户获得 1、2、3 等,即输入“是”的次数。

这里的问题是如何使用yield来演示这样的例子。在我下面写的代码中,我总是得到 generator object returned 而不是 n 的值。我怎样才能得到整数值 n returned 呢?

def yes_times(answer):
    n = 0
    if answer == 'yes':
        n = n + 1
        yield n


answer = raw_input('"yes" or "no": ')
times = yes_times(answer)
print 'You answered yes ' + str(times) + ' times'

谢谢。

问题是您正试图将生成器当作一个函数来使用。我强烈建议您阅读在线教程,直到您掌握其中的区别——毕竟,这就是我避免犯这个错误的方式。 :-)

你的说法

times = yes_times(answer)

实例化生成器,就是你打印的时候得到的。相反,您需要使用 next 函数 ...

times = next(yes_times(answer))

... 或正确使用可以满足您需要的生成器。生成器的一般用途是将其识别为 数据流 ,类似于

for times in yes_times(answer):

但是,这需要您更新生成器以获取输入本身。

这足以让你感动吗?

I'm trying to demonstrate how yield in Python is used.

... example problem ...

The issue here is how to use yield to demonstrate such example.

你在倒退。

不要通过选择一些与生成器行为无关的任意示例来演示如何使用 yield,并尝试使用 yield.

来实现它

相反,选择 yield 擅长的东西并加以实施 - 最好使用类似的非 yield 实施,这样您就可以展示优势。


简单示例:range

的玩具实现
def naive_range(begin, end):
    i = begin
    result = []
    while i < end:
        result.append(i)
        i = i + 1
    return result

def generate_range(begin, end):
    i = begin
    while i < end:
        yield i
        i = i + 1

现在,您能说出简单实施的缺点吗?什么时候会明显比生成器差,为什么?

对于你的例子,你可以试试:

def yes_times(answer = None):
    count = 0
    while True:
        if answer=="yes":
            count += 1
            answer = yield count
        else:
            answer = yield count


gen = yes_times()
gen.next()
while True:
    answer = raw_input('"yes" or "no": ')
    print 'You answered yes ' + str(gen.send(answer)) + ' times'