python yield 理解

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件事

  1. 返回右边的值, 类似retrun
  2. 接收一个值,类似传参

用法

  1. 当生成器, 类似 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

  1. 特殊的加法器
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

注意:

  1. 第一次send必须是send(None) , 因为第一次调用send只是到了 yield右边,没有获取参数。 第二次调用才获取参数
  2. 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的比较容易看,因为内部一个特殊的变量。 可以说闭包函数就是有状态的函数

原文地址:https://www.cnblogs.com/hustcpp/p/13157544.html