> 文章列表 > yield用法理解,配有代码块和解析

yield用法理解,配有代码块和解析

yield用法理解,配有代码块和解析

包含 yield 关键字的函数,是一个生成器

yield和return的区别

1、return是返回return关键字的值,被调用一次就返回一次,return只能放在一个函数代码块的最后面,运行到return的时候,就结束循环,结束这个函数代码块

2、yield后面可以放置下一行代码,但是每次被循环调用的时候,运行碰到yield就返回yield的值,然后结束这一次调用,内部保留上一次运行的结果,下次调用从yield后面的语句开始执行,直到再次遇到yield

(1)

def testA(a):b = [1,2,3]print("调用开始")for m in range(0,len(b)):print("---start---")a.append(m)yield aprint("x:",a)def runtestA():a=[4,5,6]g = testA(a)for i in g:print("y:",i)runtestA()

#运行结果

调用后
调用开始
---start---
y: [4, 5, 6, 0]
x: [4, 5, 6, 0]
---start---
y: [4, 5, 6, 0, 1]
x: [4, 5, 6, 0, 1]
---start---
y: [4, 5, 6, 0, 1, 2]
x: [4, 5, 6, 0, 1, 2]

解析:程序开始运行,调用testA函数,因为里面包含了yield,所以这个函数没有真正运行,而是得到一个生成器g,当开始for循环 i in g的时候,才开始运行testA函数,这也是为什么打印的“调用后”反而在“调用开始”之前 ;

运行testA函数,进入for循环,打印--start–,程序遇到yield,返回a的值,程序停止,然后在runtestA里面继续执行程序,打印y的值;

接着继续运行,就从刚刚遇到yield之后开始运行,打印x的值,为生成器的第一个值,然后在for循环里面继续运行,打印--start–,遇到yield,程序停止。。。一直重复,直到循环结束

(2)

def testA(a):b = [1,2,3]print("调用开始")for m in range(0,len(b)):print("---start---")a.append(m)yield aprint("x:",a)def runtestA():a=[4,5,6]g = testA(a)print("调用后")for i in g:print("y:",i)i.pop(0)print("newy:",i)

#运行结果

调用后
调用开始
---start---
y: [4, 5, 6, 0]
newy: [5, 6, 0]
x: [5, 6, 0]
---start---
y: [5, 6, 0, 1]
newy: [6, 0, 1]
x: [6, 0, 1]
---start---
y: [6, 0, 1, 2]
newy: [0, 1, 2]
x: [0, 1, 2]

解析:程序开始运行,调用testA函数,因为里面包含了yield,所以这个函数没有真正运行,而是得到一个生成器g,当开始for循环 i in g的时候,才开始运行testA函数;

运行testA函数,进入for循环,打印–start–,程序遇到yield,返回a的值,程序停止,到这里都和第一个代码的流程一样;

接着运行 runtestA,打印y的值后,将 第一个i值,也就是[4,5,6,0] 删除了第一位数,打印newy的值:[5,6,0];

接着继续运行,就从刚刚遇到yield之后开始运行,打印x的值,为生成器的第一个值,也就是[5,6,0],接着将第一个值继续投入循环,碰到yield,返回生成器内的第二个值,程序停止,继续运行runtestA,打印y 的值,为[5,6,0,1],接着继续删除列表第一个值,返回newy=[6,0,1],不断循环,直到生成器内循环结束

(3)

def testA(a):b = [1,2,3]print("调用开始")for m in range(0,len(b)):print("---start---")a.append(m)yield aa = [4,5,6]print("x:",a)def runtestA():a=[4,5,6]g = testA(a)print("调用后")for i in g:print("y:",i)i.pop(0)print("newy:",i)

运行结果: