大胡子

yield与yield from的思考

引入始末

python3中出现的yield from对coroutine编程提供了极大的好处,那么在之前出现的yield关键字,充当一个什么样的作用呢。
原本的yield语句只能将cpu控制权还给调用者,(这里引申出一个重要的一点就是多线程编程与协程编程同样都是切换,一个是在cpu角度,一个是在用户程序角度),当你想要在一个generater或者couroutine里带有yield语句的逻辑重构到另外一个generater中的时候,会非常麻烦。因为外层的生成器要为里层的生成器做消息传递,所以就需要吧这一层消息封装起来,这样有了yield from的出现

例子说明

当我们简单的使用yield去进行嵌套generater编程的时候,那么我们的代码会非常的繁琐,那么我们一起看看

1
2
3
4
5
6
7
8
9
10
11
def inner():
coef = 1
total = 0
while True:
try:
input_val = yield total
total = total + coef * input_val
except SwitchSign:
coef = -(coef)
except BreakOut:
return total

那么外层的将会是这样,当然消费者生产者模型跟这个非常像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def outer1():
print("Before inner(), I do this.")
i_gen = inner()
input_val = None
ret_val = i_gen.send(input_val)
while True:
try:
input_val = yield ret_val
ret_val = i_gen.send(input_val)
except StopIteration:
break
except Exception as err:
try:
ret_val = i_gen.throw(err)
except StopIteration:
break
print("After inner(), I do that.")

那么如果说我们将其换成python3中yield from模式,那么我么就会得到如下的代码

1
2
3
4
def outer2():
print("Before inner(), I do this.")
yield from inner()
print("After inner(), I do that.")

我们可以发现内外层的行为非常一致,消息一层一层的传递,外层对内层的调度,yied from就封装了消息传递和调度作用