Python函数(十一)-生成器
首先看一下什么是列表生成式
>>> [i*2 for i in range(10)] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> a=[] >>> for i in range(10): ... a.append(i*2) ... >>> a [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
这一句代码就实现了三句代码的效果,这一句代码就是列表生成式
列表如果存的数据太多,就会占用很大的存储空间
如果只取列表中的一些数据,那么其它不用的数据占用的存储空间就白占了
生成器也能存储数据,但是它只记录当前数据,剩下的数据都还没生成,这样就不会占用太多的存储空间
怎么创建一个生成器呢?
>>> [i*2 for i in range(10)] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> (i*2 for i in range(10)) <generator object <genexpr> at 0x0000021C9C2E5258>
这样就是一个生成器了,没有直接生成数据
要取一个数据就生成一个数据
那么怎么获取生成器里的数据呢?
>>> b = (i*2 for i in range(10)) >>> b <generator object <genexpr> at 0x0000021C9C2E5308> >>> b.__next__() 0 >>> b.__next__() 2 >>> b.__next__() 4 >>> next(b) 6 >>> next(b) 8 >>> next(b) 10
生成器使用next()方法获取数据,next(b),这是Python3和Python2通用的方法
Python3中还可以用__next__()方法,b.__next__()
Python2中用next()方法,b.next()
但是用next()方法一次次取数据太麻烦,所以通常都用for循环来打印数据
>>> c = (i*2 for i in range(10)) >>> for n in c: ... print(n) ... 0 2 4 6 8 10 12 14 16 18
如果函数里有yield关键字,这个函数就是生成器
# -*- coding:utf-8 -*-
__author__ = "MuT6 Sch01aR"
def test(n):
m = 0
b = 0
while m<n:
print("before yield")
yield b
b = b+3
print("after yield")
m =m+1
return "test return"
a =test(10)
while True:
try:
b = a.__next__()
print("in the next",b)
except StopIteration as e:
print(e.value) #StopIteration的value为生成器的返回值
exit()
运行结果

运行过程:
首先是调用test()函数

然后执行while循环

到__next__()方法的时候,跳到test()函数

执行完yield后,没继续执行下面的语句,而是返回到__next__()方法后的语句

执行完该语句后继续执行while循环,执行__next__()方法
然后又跳转到yield后的语句

生成器调用next()方法的时候执行,执行到生成器中的yield的时候返回,然后执行next()方法后的语句,再执行到next()方法的时候,就会跳到执行yield的语句,之后执行yield后的语句
用生成器实现单线程多并发
# -*- coding:utf-8 -*-
__author__ = "MuT6 Sch01aR"
import time
def consumer(name):
print('%s准备吃包子' %name)
while True:
baozi = yield
print('%s包子来了,被%s吃了' %(baozi,name))
def producer():
c = consumer('张三')
c2 = consumer('李四')
c.__next__()
c2.__next__()
print('我开始准备做包子了')
for i in range(10):
time.sleep(1)
print('我做了2个包子')
c.send('肉') #调用yield,并传值
c2.send('菜')
if __name__ == '__main__':
producer()
send方法不仅可以调用yield,还给yield传值
运行结果

实现了单线程多并发的效果

浙公网安备 33010602011771号