生成器&迭代器
生成器的特性
1、生成器是一个有yield关键字的函数对象,yield暂停并保存并返回调用结果
2、第一次通过next开始运行这个函数,以后每次next就从yield开始继续运行函数
3、可以用send给生成器的yield关键字传值并激活函数
''' 生成器:循环n次找出第n个元素 可以由上一个数据推算出下一个数据。 一边循环一边计算的机制叫做生成器 ''' # 列表生成式,列表的初始化[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] l = [abs(i) for i in range(10)] # 变成生成器,相当于准备了一个算法, # 不访问不会生成数据,取数据只能通过for循环一个一个取 # 生成器有g.__next__()方法, # 取出当前存储值的下一个值,不能往后退, # 一次只能迈一步,不能迈大步子 g = (i*2 for i in range(10)) ''' 自定义生成器 用函数实现斐波那契数列长度10 1,1,2,3,5,8,13,21,34,55.. ''' def fib(length): n, a, b = 0, 0, 1 while(n < length): print(b) a, b = b, a+b n += 1 # 把fib变为生成器 def fib(length): n, a, b = 0, 0, 1 while(n < length): yield b a, b = b, a+b n += 1 return "生成器结束" fib_generator = fib(10) print(fib_generator.__next__()) print(fib_generator.__next__()) # 有了生成器后可以让函数停在某个地方, # 做点其他事之后回来继续运行 # 让主线程可以来回调用不同的函数, # 在各个工作之间不停的切换 print("做点其他的事情.........") for i in fib_generator: print(i) # 让生成器运行到结束(如果能结束的话) while True: try: print("斐波那契:",next(fib_generator)) except StopIteration as e: print("生成器函数结束后的返回值:",e.value) break # 生成器第一次调用next方法就开始执行生成器函数,执行到yield返回给next方法。 # 第二次执行next就接着上一次的yield后执行,执行到yield又返回,依次类推 # yield的作用是暂停并记住当前状态,并返回 # 生成器中return的作用是异常的时候打印消息
通过生成器并行计算实现单线程下的异步=单线程下的并行效果=协程
协程是比线程更小的单位
因为CPU效率高,可以很快的运行和在不同的任务中来回切换
生产者消费者模式:
''' 生产者消费者模型:一个负责生产producer包子,一个负责吃consumer包子 __next__()只是启动yield,send(value)即启动yield又给yield传值value 消费者不停的吃,生产者不停的喂, 生产者可以有很多,消费者也可以有很多,喂的方式也是灵活的 ''' def consumer(name): # 消费者 while True: print("[%s]准备吃包子了" % name) baozi = yield # print(baozi,name) print("包子[%s]来了,被[%s]吃了" % (baozi, name)) def producer(con): for i in range(4): print("开始做包子喂给消费者了----------------") con.send(i) c = consumer("张三") c.__next__() producer(c) ''' [张三]准备吃包子了 # 执行c.__next__()后打印 开始做包子喂给消费者了---------------- 包子[0]来了,被[张三]吃了 [张三]准备吃包子了 开始做包子喂给消费者了---------------- 包子[1]来了,被[张三]吃了 [张三]准备吃包子了 开始做包子喂给消费者了---------------- 包子[2]来了,被[张三]吃了 [张三]准备吃包子了 开始做包子喂给消费者了---------------- 包子[3]来了,被[张三]吃了 [张三]准备吃包子了 '''
123
1
1
1
1
1