生成器函数

生成器函数是一个迭代器, 不过只能遍历其一次, 这是因为生成器并不将数据存储在内存之中, 生成完数据后并不保存下来.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

list=(i for i in range(5))

for i in list:
print(i)

print("---")
for i in list:
print(i)

out:
0
1
2
3
4
---
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

def createGenerator():
for i in range(5):
yield i*i

gen=createGenerator()
for i in gen:
print(i)

print("---")
for i in gen:
print(i)
out:

0
1
4
9
16
---

另外, 生成器函数并不是再调用的时候就运行的, 而是在遍历的时候才运行, 在上述代码中, 意味着生成器函数是在执行for i in gen:时才运行的.

解释器是如何知道其是生成器函数的呢? 当解释器发现yield时, 就知道该函数是个生成器函数, 它会设置一个标识来标记这一情况, 调用type也可以发现这一情况.

1
2
3
4
5
6
7
8
9
#生成器标志位在第5位
generator_bit=1<<5
b=bool(createGenerator.__code__.co_flags & generator_bit)
print(b)
print(type(createGenerator))

out:
True
<class 'generator'>

参考文章:

A Web Crawler With asyncio Coroutines

What does the yield keyword do