1、yield使用
1)函数中使用yield,可以使函数变成生成器。一个函数如果是生成一个数组,就必须把数据存储在内存中,如果使用生成器,则在调用的时候才生成数据,可以节省内存。
1)函数中使用yield,可以使函数变成生成器。一个函数如果是生成一个数组,就必须把数据存储在内存中,如果使用生成器,则在调用的时候才生成数据,可以节省内存。
2)生成器方法调用时,不会立即执行。需要调用next()或者使用for循环来执行。使用for循环不需要自己捕获StopIteration异常。使用next()方法,当生产器方法执行结束会抛出StopIteration异常(只要不是使用yield返回数据,都会抛出StopIteration异常)。
yield不仅可以返回值,也可以接收值。下面面示例为生产消费模式。生产者生产一条记录,消费者消费一条记录。
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print ('[CONSUMER] Consuming %s ...' % n)
r = '200 OK'
def producer(c):
# 在一个生成器函数未启动之前,不能传递数值进去。必须先传递一个None进去或者调用一次next(g)
# 方法,才能进行传值操作。
c.send(None)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s ...' % n)
r = c.send(n)
print('[PRODUCER] Consuming return: %s' % r)
c.close()
c = consumer()
producer(c)
需要注意send传递给yield的参数值和yield的返回值的区别,看下面的例子:
def foo():
food_list = []
while True:
#food是send发送给yield的参数值,在接下来 的语句中使用,foodlist是yield的返回值
food = yield food_list #返回添加food的列表
food_list.append(food)
print("elements in foodlist are:",food)
g = foo()
print(g.send('苹果'))
print(g.send('香蕉'))
print(g.send('菠萝'))
而yield from则为了让生成器(带yield函数),能简易的在其他函数中直接调用。
def htest():
i = 1
while i < 4:
n = yield i
if i == 3:
return 100
i += 1
def itest():
val = yield from htest()
print(val)
t = itest()
t.send(None)
j = 0
while j < 3:
j += 1
try:
t.send(j)
except StopIteration as e:
print('异常了')