python进阶:生成器与yield关键字在函数中的执行顺序问题

  1. 概述
    生成器:按照程序员制定的规则,快速生成对象
    特点:能提高编程效率,降低能耗
    基础语法:
    生成器对象 = (生成器规则)

            根据该语法格式,赋值生成器对象,直接打印时输出的是对象的地址,对此python中为了获取其内部的数据有两种API可供选择:
            (1)通过for循环遍历获取所有数据
            (2)通过next()逐次获取每个数据

  2. yield关键字的基础使用
    # 定义一个简单函数,快速生成列表元素,存放到生成器中,并返回生成器对象
    def func():
        for i in range(5):
            yield [i,i+1]     # 逐次存放列表元素到生成器中
    
    
    
    if __name__ == '__main__':
        my_func = func()
        print(my_func)  # 直接打印,为生成器对象的地址
        # 法一 获取生成器中的所有元素
        for data in my_func:
            print(data)
        # 法二 逐个获取生成器中的所有元素
        for i in range(5):
            for data in next(my_func):
                print(data)
    """
    值得注意的是,法一执行后,再执行法二,会出现无数据的情况,这种情况与文件指针指向末尾类同
    """
  3. 执行顺序
    拿简单输出print为例,yield的执行顺序特殊在:逐次,具体如下:
    # 定义函数
    def func():
            for i in range(5):
                print(i)
            print('函数执行完毕')
            return func
    
    # main
    if __name__ == '__main__':
        my_func = func()  # 赋函数返回值给my_func变量,同时执行函数中的输出语句

    执行结果:


    而改用yield对其稍加修改,如下:
     

    # 定义函数
    def func():
        for i in range(5):
            yield i  # 将元素i封装到生成器中
            print(f'第{i + 1}次执行完毕')
        print('函数执行完毕')
    
    
    # main
    if __name__ == '__main__':
        my_generator = func()
        # 通过遍历获取全部数据
        for data in my_generator:
            print(data)
    

    执行结果如下:

    可见,函数func调用赋值时,并未将其余两个print语句执行,反而在遍历获取所有数据时进行了打印输出。此时,我们再对主程序做下修改,更好的观察下,yield语句的执行顺序:
     

    # 定义函数
    def func():
        for i in range(5):
            yield [i]  # 将列表元素i封装到生成器中
            print(f'第{i + 1}次执行完毕')
        print('函数执行完毕')
    
    
    # main
    if __name__ == '__main__':
        my_generator = func()
        # 利用next语句获取生成器中的第一个元素
        print(next(my_generator))
        print('-'*80)
        # 利用next语句获取生成器中的第二个元素
        print(next(my_generator))
        print('-'*80)
        # 利用next语句获取生成器中的第三个元素
        print(next(my_generator))
        print('-'*80)
        # 利用next语句获取生成器中的第四个元素
        print(next(my_generator))
        print('-'*80)
        # 利用next语句获取生成器中的第五个元素
        print(next(my_generator))
        print('-'*80)
        # 再使用一次next,会出现迭代错误
        print(next(my_generator))
        print('-'*80)

    执行结果如下:

    观测到的现象:
    ①函数中yield的封装是逐次的,不是一次性完成的,主程序每进行一次提取,相应的会提前进行一次封装
    ②循环提取时,由于封装也是循环的,故每封装一次,print(f'第{i+1}次执行完毕')
    ③当提取完最后元素再使用next时,程序会报错同时print('函数执行完毕')

    结论:
    yield与return类同,但不像return那么“霸道”,直接终止后续语句的执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值