> For the complete documentation index, see [llms.txt](https://jarvisma.gitbook.io/pythonlearn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jarvisma.gitbook.io/pythonlearn/4.3-sheng-cheng-qi/chapter4.3.1.md).

# 4.3.1 生成器的定义

先给出生成器的定义：

1. 只要函数体重有 `yield` 关键字，这个函数就是生成器函数
2. 调用生成器函数，会得到生成器，生成器函数可以理解为生成器的工厂
3. 调用 `next` 函数会激发生成器的下一个值

举个例子:

```python
def gen():
    print('Start')
    yield 1
    print('Continue')
    yield 2
    yield 3

g = gen()       # 注意，这里没有输出！！！
print(next(g))  # 输出两行，start 和 1
print(next(g))  # 输出两行，Continue 和 2
print(next(g))  # 输出 2
print(next(g))  # 抛出异常 StopIteration
```

从输出内容中可以看出，调用生成器函数会返回一个生成器对象，但生成器函数中的代码不会执行。在调用 `next(g)` 函数时才会执行生成器函数的代码，阻塞在 `yield x` 这一行，并且`next(g)` 函数的返回值就是 `x`。第几次调用 `next` 函数，就会阻塞在第几个 `yield` 处。如果是第一次接触生成器，这个逻辑需要反复体会几次。

生成器的使用方式和迭代器一致，我们可以认为生成器都是迭代器，都实现了迭代器接口。因此 4.2.5 节中的代码就很容易解释了。当外部调用 `iter()` 函数时，实际上 `__iter__` 方法中的代码并没有被立刻执行，而是返回了一个生成器。
