/ 2019-05-21
yield关键字,可以让我们定义一个生成器函数。
def generator_func():
print('a')
yield 1
g = generator_func()
print(g)
>>> <generator object generator_func at 0x10e178b88>
使用next函数从生成器中取值
def generator_func():
print('a')
yield 1
g = generator_func()
ret1 = next(g)
print(ret1)
>>>
a
使用next可以推动生成器的执行,下面的代码,我们可以看到每一次执行next可以让generator_func中代码从上一个位置开始继续执行到yield,并且将yield后面值返回到函数外部,最终我们可以执行到yield 3。
def generator_func():
print('a')
yield 1
print('b')
yield 2
print('c')
yield 3
print('d')
g = generator_func()
ret1 = next(g)
print(ret1)
ret2 = next(g)
print(ret2)
ret3 = next(g)
print(ret3)
>>>
a
b
c
当函数中已经没有更多的yield时继续执行next(g),遇到StopIteration
def generator_func():
print('a')
yield 1
print('b')
yield 2
print('c')
yield 3
print('d')
g = generator_func()
ret1 = next(g)
print(ret1)
ret2 = next(g)
print(ret2)
ret3 = next(g)
print(ret3)
next(g)
next和StopIteration
send向生成器中发送数据。send的作用相当于next,只是在驱动生成器继续执行的同时还可以向生成器中传递数据。
import numbers
def cal_sum():
sum_num = 0
while True:
num = yield
if isinstance(num,numbers.Integral):
sum_num += num
print('sum :',sum_num)
elif num is None:
break
g = cal_sum()
g.send(None) # 相当于next(g),预激活生成器
g.send(31)
g.send(25)
g.send(17)
g.send(8)
>>>
sum : 31
sum : 56
sum : 73
sum : 81
生成器中的return和StopIteration
import numbers
def cal_sum():
sum_num = 0
while True:
num = yield
if isinstance(num,numbers.Integral):
sum_num += num
print('sum :',sum_num)
elif num is None:
break
return sum_num
g = cal_sum()
g.send(None) # 相当于next(g),预激活生成器
g.send(31)
g.send(25)
g.send(17)
g.send(8)
g.send(None) # 停止生成器
>>>
sum : 31
sum : 56
sum : 73
sum : 81
Traceback (most recent call last):
File "/Users/jingliyang/PycharmProjects/python的进阶/manager.py", line 19, in
g.send(None)
StopIteration: 81
import numbers
def cal_sum():
sum_num = 0
while True:
num = yield
if isinstance(num,numbers.Integral):
sum_num += num
print('sum :',sum_num)
elif num is None:
break
return sum_num
g = cal_sum()
g.send(None) # 相当于next(g),预激活生成器
g.send(31)
g.send(25)
g.send(17)
g.send(8)
try:
g.send(None) # 停止生成器
except StopIteration as e:
print(e.value)
异常处理以及获取return的值
使用throw向生成器中抛一个异常
def throw_test():
print('a')
yield 1
print('b')
yield 2
g = throw_test()
next(g)
g.throw(Exception,'value error')
>>>
a
Traceback (most recent call last):
File "/Users/jingliyang/PycharmProjects/python的进阶/manager.py", line 32, in <module>
g.throw(ValueError,'value error') # throw和send、next相同,都是驱动生成器继续执行,只不过throw用来向生成器中抛一个异常
File "/Users/jingliyang/PycharmProjects/python的进阶/manager.py", line 26, in throw_test
yield 1
ValueError: value error
def throw_test():
print('a')
try:
yield 1
except ValueError:
pass
print('b')
yield 2
g = throw_test()
next(g)
ret = g.throw(ValueError,'value error') # throw和send、next相同,都是驱动生成器继续执行,只不过throw用来向生成器中抛一个异常
print(ret)
>>>
a
b
throw+异常处理
使用close关闭一个生成器
def throw_test():
print('a')
yield 1
print('b')
yield 2
g = throw_test()
ret1 = next(g)
print(ret1)
g.close()
next(g)
>>>
a
Traceback (most recent call last):
File "/Users/jingliyang/PycharmProjects/python的进阶/manager.py", line 45, in <module>
next(g)
StopIteration
(0)