生成器
生成器

生成器

生成器提供了一种优雅的方法,可以让编写返回元素序列的函数所需的代码变得简单、高效。基于yield语句,生成器可以暂停函数并返回一个中间结果。该函数会保存执行上下文,稍后在必要时可以恢复。

def fibonacci():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a+b

这个函数返回一个generator对象,是特殊的迭代器,它知道如何保存上下文,可以被无限次调用,每次都会生成序列的下一个元素。

def power(values):
    for value in values:
        print('powering %s' % value)
        yield value
def adder(values):
    for value in values:
        print('adding to %s' % value)
    if value % 2 == 0:
        yield value +3
    else:
        yield value + 2    

生成器的另一个重要特性,就是能够利用next函数与调用的代码进行交互。yield变成了一个表达式,而值可以通过名为send的新方法进行传递。

def psychologist():
    print('Please tell me your problems')
    while True:
        answer = (yield)
        if answer is not None:
            if answer.endswith('?'):
                print("Don't ask yourself too much questions")
            elif 'good' in answer:
                print("Ahh that's good, go on")
            elif 'bad' in answer:
                print("Don't be so nagative")

下面是调用psychologist()的示例对话

In [12]: free = psychologist()

In [13]: next(free)
Please tell me your problems

In [14]: free.send('I feel bad')
Don't be so nagative

In [15]: free.send('Fuck you?')
Don't ask yourself too much questions

In [16]: free.send('ok, fuck your mom is good')
Ahh that's good, go on

send的作用和next类似,但会将函数定义内部传入的值变成yield的返回值。incident,这个函数可以根据客户端代码来改变自身行为。为完成这一行为,还添加了另外两个函数:throwclose。它们将向生成器抛出错误。

  • throw:允许客户端代码发送要抛出的任何类型的异常。
  • close:作用相同,但会引发特定的异常——GeneratorExit。这种情况下,生成器函数必须再次引发GeneratorExit或StopIteration。

发表回复

您的电子邮箱地址不会被公开。