yield 是python的关键字,我理解是可以用来打断和继续函数运行
我们可以从国外的交通指示牌理解
美国交通规则中【baiyield】的意思是
【让道】
1)duYou must yield the right-of-way to all approaching vehicles and pedestrians.
(你必zhi须给所有正要靠近的车辆和行人让dao路)
2)The car turning left must yield the right-of-way to the other car.
(左转车辆应该让其他车辆)
3)You must yield the right-of-way to any vehicle which has entered the intersection on your right or is approaching the intersection from your right.
(你必须给任何驶入你右车道或靠近你右边车道的车让行)
总之 yield 就是让路的意思,而程序执行到yield 就停止
下面是一个无尽的yield, 因为有while 死循环,可以一直调用next或者send
def func1():
while True: # 1
res = yield 4 # 2l 2r
print(res) # 3
推演next 的调用
f = func1() # 这里获得一个`generator object`
next(f)
next(f)
print(next(f))
第1个next(f):
graph TB
1[判断循环条件] --> 2r[返回return4]
第2个next(f):
graph TB
2l[接受一个值给res] --> 3[打印] --> 1[判断循环条件] --> 2r[返回return]
第3个next(f):
graph TB
2l[接受一个值给res] --> 3[打印] --> 1[判断循环条件] --> 2r[返回return]
可以见,yield 干了2件事
- 返回右边的值, 类似retrun
- 接收一个值,类似传参
用法
- 当生成器, 类似 range。 以前的range是生成一个数组, 而现在range是生成器。
def func1():
total = 0
while True:
yield total
total += 1
g = func1()
print(next(g))
print(next(g))
print(next(g))
打印 0,1,2
- 特殊的加法器
def func1():
total = 0
while True:
res = yield total
total += res
g = func1()
g.send(None)
g.send(1)
g.send(2)
输出 0 1 3
注意:
- 第一次send必须是send(None) , 因为第一次调用send只是到了 yield右边,没有获取参数。 第二次调用才获取参数
- send 和 next 一样,都能驱动函数执行, 但send 还有传参的功能
顺便看下js的闭包
function func1() {
var i = 10
function func2() {
i = i + 1;
return i;
}
return func2;
}
var fun = func1()
console.log(fun())
console.log(fun())
console.log(fun())
执行结果:
11 12 13
yield 和 闭包是类似的, 看js的比较容易看,因为内部一个特殊的变量。 可以说闭包函数就是有状态的函数