1、生成器介绍

首先请确信,生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中。

2、生成器函数

1)、自定义生成器

1 defgenerator1():2 yield 1

3 yield 2

4 yield 3

5

6

7 g =generator1()8 print(next(g))9 print(next(g))10 print(next(g))

#执行结果

1

2

3

我们需要注意的是:第一次调用生成器的next方法时,生成器才开始执行生成器函数(而不是构建生成器时),直到遇到yield时暂停执行(挂起),并且yield的参数将作为此次next方法的返回值;

1 >>> defgen():2 ... yield 1

3 ... yield 2

4 ...5 >>> g =gen()6 >>>type(g)7

当调用next方法时生成器函数结束,再次调用next方法将抛出StopIteration异常。(即for循环的终止条件)

1 >>>next(g)2 1

3 >>>next(g)4 2

5 >>>next(g)6 Traceback (most recent call last):7 File "", line 1, in

8 StopIteration

其他补充知识:

1、生成器带参数

1 >>> def counter(start=0):2 ... whileTrue:3 ... yieldstart4 ... start +=1

5 ...6 >>> count =counter()7 >>>next(count)8 09 >>>next(count)10 1

11 >>>next(count)12 2

13 >>>next(count)14 3

协同程序(coroutine)

1、可以方便地挂起、恢复,并且有多个入口点和出口点;

2、多个协同程序间表现为协作运行,如A的运行过程中需要B的结果才能继续执行。

协程的特点决定了同一时刻只能有一个协同程序正在运行。得益于此,协程间可以直接传递对象而不需要考虑资源锁、或是直接唤醒其他协程而不需要主动休眠,就像是内置了锁的线程。在符合协程特点的应用场景,使用协程无疑比使用线程要更方便。

协程函数的例子:

文件a.txt,打印出所有含有“apple”的行

apple 10 3

iphone 4000 1

macbook 3000 2

chicken 10 3

apple 11 22

apple 20 23

1 defcat(file_path):#定义cat函数寻找文件读取内容2 with open(file_path) as f:3 for line inf:4 if notline:5 continue

6 else:7 yieldline8

9 defgrep(source, keywords):#判断函数,是否含有相应的关键字10 if keywords insource:11 yield source

#执行代码

1 source1 = cat("a.txt") #生成器2 print(source1)3 for i insource1:4 g1 = grep(i,"apple")5

6 for i ing1:7 print(i, end="")

#执行结果

apple 10 3

apple 11 22

apple 20 23

生成器中的send(value)方法。send是除next外另一个恢复生成器的方法。此时yield语句变成了yield表达式,这意味着yield现在可以有一个值,而这个值就是在生成器的send方法被调用从而恢复执行时,调用send方法的参数

1 from urllib.request importurlopen2

3 defget():4 whileTrue:5 url = yield

6 res =urlopen(url).read()7 print(res)

1 g =get()2 next(g)3 g.send("http://www.sina.com.cn")

注意:

1、调用send传入非None值前,生成器必须处于挂起状态,否则将抛出异常。未启动的生成器仍可以使用None作为参数调用send。

2、如果使用next恢复生成器,yield表达式的值将是None。