十一、Python yield用法

Python yield

1、定义

     函数中带有关键字yield,就是  generator(生成器),带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator(生成器)

2、解释

        这个生成器(就说是函数吧)每次执行到 yield 关键 时,函数就返回yied后面的值,yied后面的代码将不再执行(相当于直接return)。下次在调用生成器的next()函数,代码从 yield 关键词 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield

 3、实战中寻找真理 next()函数

def fabNum():
    print("starting...")
    while True:
        num = yield 2
        print("num的值为:",res)
g = fabNum()
print(next(g))
print("-"*20)
print(next(g))

  执行结果:

C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\python.exe F:/python-space/test/ProTest.py
starting...
2
--------------------
num的值为: None
2

下面需要我们要有一点儿耐心,我们来一步一步的分析:

      1)程序开始执行以后,因为fabNum函数中有yield关键字,所以fabNum函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

      2)直到调用next方法,fabNum函数正式开始执行,先执行fabNum函数中的print方法,然后进入while循环

      3)程序遇到yield关键字,然后把yield想成return,return了一个2之后,程序停止,并没有执行赋值给num操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,

      4)程序执行print("-"*20),输出20个*

      5)又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行num的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候num赋值是None,所以接着下面的输出就是num:None,

      6)程序会继续在while里执行,又一次碰到yield,这个时候同样return 出2,然后程序停止,print函数输出的2就是这次return出的2.
 

4、实践中寻找真理 send()函数

def fab():
    print("starting...")
    while True:
        num = yield 2
        print("num的值为:",num)
g = fab()
print(next(g))
print("-"*20)
print(g.send(3))

  输出结果:

starting...
2
--------------------
num的值为: 3
2

         从上面的2次打印结果对比,可以看出那个num的值从None变成了3,这到底发生了什么呢?

         因为生成器的send()函数可以发送一个参数给num,调用next()函数,return的时候,并没有把2赋值给num,下次执行的时候只好继续执行赋值操作,只好赋值为None了,而如果用send的话,开始执行的时候,先接着上一次(return 2之后)执行,先把3赋值给了num,然后执行next的作用,遇见下一回的yield,return出结果后结束。

    1)程序执行g.send(3),程序会从yield关键字那一行继续向下运行,send会把3这个值赋值给num变量

    2)由于send方法中包含next()方法,所以程序会继续向下运行执行print方法,然后再次进入while循环

    3)程序执行再次遇到yield关键字,yield会返回后面的值后,程序再次暂停,直到再次调用next方法或send方法。
 

5、生成器优点

     1)使用方便

     2)比rang()函数(生成的结果是list,list是需要优化的)生成的占用更少的存储空间

def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print('生成的数字是:',n)

结果:

生成的数字是: 1
生成的数字是: 2
生成的数字是: 3
生成的数字是: 4
生成的数字是: 5
生成的数字是: 6
生成的数字是: 7
生成的数字是: 8
生成的数字是: 9
生成的数字是: 10

6、给大佬奉茶

   源码:

#1、生成器的简单使用
print('1、生成器的简单使用')
def fabNum():
    print("starting...")
    while True:
        num = yield 4
        print("num的值为:",num)
g = fabNum()
print(next(g))
print("-"*20)
print(next(g))

#2、生成器send()的使用
print()
print('*'*20)
print('2、生成器send()的使用')
def fab():
    print("starting...")
    while True:
        num = yield 2
        print("num的值为:",num)
g = fab()
print(next(g))
print("-"*20)
print(g.send(3))

#3、举个例子
print()
print('3、举个例子')
def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print('生成的数字是:',n)


结果:

C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\python.exe F:/python-space/test/ProTest.py
1、生成器的简单使用
starting...
4
--------------------
num的值为: None
4

********************
2、生成器send()的使用
starting...
2
--------------------
num的值为: 3
2

3、举个例子
starting...
生成的数字是: 1
生成的数字是: 2
生成的数字是: 3
生成的数字是: 4
生成的数字是: 5
生成的数字是: 6
生成的数字是: 7
生成的数字是: 8
生成的数字是: 9
生成的数字是: 10

Process finished with exit code 0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值