文章源自查看博客:python中yield的用法详解——最简单,最清晰的解释_冯爽朗的博客-CSDN博客_python yield
自己整理思路使用,希望大家去看原作者的博客,讲解超级清晰且易理解!!
目录
在调用包含yield的函数时,在第一次调用时可以将yield看作return,就是返回yield之后跟的值;
再次调用包含yield函数时,将函数看作是一个生成器,是接着上一次调用运行结束的地方执行的。
具体理解看代码:
- def foo():
- print("starting...")
- while True:
- res = yield 4
- print("res:",res)
-
- g = foo()
- print(next(g))
- print("*"*20)
- print(next(g))
第一步:定义foo()函数;
第二步:定义生成器g;-- 这里不会调用foo()函数,直到运行到next()时,才真正的调用函数;
第三步: 执行定义的生成器g, 首先执行print,输出 starting...,然后进入while循环,执行res = yield 4, 这是第一次调用该函数,因此yield在这里看作是 return, 然后返回4,相当于该函数执行完成;
第四步: 执行 print("*"*20);
第五步:再次执行定义的生成器,这次执行是接着上一次执行结束的地方开始执行,也就是从 res = yield 4的地方开始执行,此时是进行赋值操作,因为原本的4已经在上一步被返回出去,此时的赋值操作,res应该被赋值为None;
第六步,然后接着向下执行,返回res的值,然后再进行while循环,当作return 返回4,执行结束;
因此上述代码的执行结果为:
- starting...
- 4
- ********************
- res: None
- 4
send()是发送一个值到yield处;
具体代码:
- def foo():
- print("starting...")
- while True:
- res = yield 4
- print("res:",res)
-
- g = foo()
- print(next(g))
- print("*"*20)
- print(g.send(7))
与第一个例子不同的是,将最后一行换掉了;
执行步骤:
第一步:定义foo()函数;
第二步:定义生成器g;-- 这里不会调用foo()函数,直到运行到next()时,才真正的调用函数;
第三步: 执行定义的生成器g, 首先执行print,输出 starting...,然后进入while循环,执行res = yield 4, 这是第一次调用该函数,因此yield在这里看作是 return, 然后返回4,相当于该函数执行完成;
第四步: 执行 print("*"*20);
第五步:再次执行定义的生成器,这次执行是接着上一次执行结束的地方开始执行,也就是从 res = yield 4的地方开始执行,此时是进行赋值操作,因为这次使用的为send(7), 实际上是将7发送到yield处,因此res便被赋值为7;
第六步,然后接着向下执行,返回res的值,然后再进行while循环,当作return 返回4,执行结束;
执行结果:
- starting...
- 4
- ********************
- res: 7
- 4
节省内存;
具体列子:
- for n in range(1000):
- a=n
使用 range(1000),会产生长度为1000的list,占用内存大;
使用yield实现上述方法:
- def foo(num):
- print("starting...")
- while num<1000:
- num=num+1
- yield num
- for n in foo(0):
- print(n)
此时占用内存便很小,不需要存1000个数;