python编程之生成器(generator)

1、生成器介绍

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

2、生成器函数

  1)、自定义生成器

 1 def generator1():
 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 >>> def gen():
2 ...     yield 1
3 ...     yield 2
4 ... 
5 >>> g = gen()
6 >>> type(g)
7 <class 'generator'>  

 当调用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 "<stdin>", line 1, in <module>
8 StopIteration

其他补充知识:

1、生成器带参数

 1 >>> def counter(start=0):
 2 ...     while True:
 3 ...         yield start
 4 ...         start +=1
 5 ... 
 6 >>> count = counter()
 7 >>> next(count)
 8 0
 9 >>> 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 def cat(file_path):#定义cat函数寻找文件读取内容
 2     with open(file_path) as f:
 3         for line in f:
 4             if not line:
 5                 continue
 6             else:
 7                 yield line
 8 
 9 def grep(source, keywords):#判断函数,是否含有相应的关键字
10     if keywords in source:
11         yield source
#执行代码
1
source1 = cat("a.txt") #生成器 2 print(source1) 3 for i in source1: 4 g1 = grep(i,"apple") 5 6 for i in g1: 7 print(i, end="")
#执行结果
<generator object cat at 0x1011030f8> apple 10 3 apple 11 22 apple 20 23

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

1 from urllib.request import urlopen
2 
3 def get():
4     while True:
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。

转载于:https://www.cnblogs.com/greatkyle/p/6694302.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的迭代器、生成器和装饰器都是非常重要的编程概念,下面分别介绍一下: 1. 迭代器 Python中的迭代器是一种可以遍历集合中元素的对象,可以使用for循环遍历集合中的元素。迭代器实现了两个方法:__iter__()和__next__()。__iter__()方法返回迭代器对象自身,__next__()方法返回集合中的下一个元素。 下面是一个简单的使用迭代器遍历列表的示例: ``` my_list = [1, 2, 3] my_iterator = iter(my_list) for i in my_iterator: print(i) ``` 2. 生成器 生成器是一种特殊的函数,可以在执行过程中多次返回值,而不是只返回一次。生成器使用yield语句返回值,可以暂停函数的执行,并在需要时继续执行。 下面是一个简单的生成器示例: ``` def my_generator(): yield 1 yield 2 yield 3 for i in my_generator(): print(i) ``` 3. 装饰器 装饰器是一种可以修改函数或类的行为的函数,可以在不修改原始代码的情况下添加额外的功能。装饰器本质上是一个可以接受函数或类作为参数的函数,可以在不修改原始函数或类的情况下修改其行为。 下面是一个简单的装饰器示例: ``` def my_decorator(func): def wrapper(): print("Before the function is called.") func() print("After the function is called.") return wrapper @my_decorator def my_function(): print("Inside the function.") my_function() ``` 在上面的代码中,我们定义了一个装饰器函数my_decorator,它接受一个函数作为参数,并返回一个新的函数wrapper。这个新函数在调用原始函数之前和之后打印一些文本。我们使用@符号将装饰器应用到my_function函数上,这样my_function函数的行为就被修改了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值