• 生成器


    生成器

    什么是生成器?

    生成的工具

    生成器是一个'自定义'的迭代器,本质上是一个迭代器

    #因为生成器内置有.__iter__()和.__next__()方法,所以生成器本身就是一个迭代器
    print(res.__iter__())
    print(res.__next__())
    #结果为
    <generator object my_range at 0x0000020BCB802348>
    1
    
    如何实现生成器?

    但凡在函数内部定义了yield,调用函数时函数体代码不会执行,会返回一个结果,该结果就是一个生成器

    def my_range(start, stop, step=1): #定义函数
        print('start...')              #打印内容为start    
        while start < stop:            #进行加了判断条件的while循环
            yield start                #返回一个结果,即生成器
            start += step   #每次取出的值都是在上一个值的基础上加上步长step
    
    
    res = my_range(1, 5)    #定义变量名res等于调用函数my_range得到的结果,结果就是一个生成器对象
    print(res)
    #结果为
    <generator object my_range at 0x0000015710A42348>
    #因为生成器的本质上是迭代器,所以我们可以用迭代取值的方式取值,即通过.__next__()
    print(res.__next__())
    #还可以直接用next取值
    print(next(res))
    print(next(res))
    print(next(res))
    print(next(res))
    #结果为
    start...
    1 #触发函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
    2 #调用next(res),函数从上次暂停的位置继续执行,直到重新遇到yield...
    3 # 周而复始...
    4 # 周而复始...
    StopIteration # 触发函数执行没有遇到yield则无值返回,即取值完毕抛出异常结束迭代
    
    yield

    有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值

    每一次yield都会往生成器对象中添加一个值

    def eater():
        print('Ready to eat')
        while True:
            food = yield
            print(f'get the food:%s,and start to eat' % food)
    
    
    g = eater() # 得到生成器对象
    print(g) 
    next(g) # 需要事先”初始化”一次,让函数挂起在food=yield,等待调g.send()方法为其传值
    next(g)
    g.send('包子')
    #结果为
    <generator object eater at 0x000001F0711121C8>
    Ready to eat
    get the food:None,and start to eat
    get the food:包子,and start to eat
    #PS:针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用g.send()方法为函数体传值,g.send(None)等同于next(g)。
    
    def init(func):
        def wrapper(*args, **kwargs):
            g = func(*args, **kwargs)
            next(g)
            next(g) #next(g)相当于g.send(None)
            g.send('鸡腿')
            return g
        return wrapper
    
    
    
    @init
    def eat():
        print('Ready to eat')
        while True:
            food = yield
            print('get the food:%s, and start to eat' % food)
    eat()
    #输出结果为
    Ready to eat
    get the food:None, and start to eat
    get the food:鸡腿, and start to eat
    

    PS:yield只能在函数内部定义

    ​ yield可以保存函数的暂停状态

    yield和return

    相同点:返回值的个数都是无限制的

    不同点:return只能返回一次值,yield可以返回多个值

    #yield也可以用于返回多次值,即变量名=yield 值的形式
    def eater():
        print('Ready to eat')
        food_list = []
        while True:
            food = yield food_list
            food_list.append(food)
    
    
    e = eater()
    next(e)
    print(e.send('牛肉'))
    print(e.send('羊肉'))
    print(e.send('红烧肉'))
    #结果为
    Ready to eat
    ['牛肉']
    ['牛肉', '羊肉']
    ['牛肉', '羊肉', '红烧肉']
    
  • 相关阅读:
    kotlin 通过 下标比对
    textarea元素调整
    jquery给两个标签绑定一个事件
    开发过程中遇到的错误
    response.setHeader各种用法详解
    如何在eclipse里删除一个类 然后SVN服务器也同时删了这个类
    @pathvariable 与@requestparam 写rest接口时遇到的
    $.getJSON
    easyUI学习
    jQuery validator addMethod 动态提示信息
  • 原文地址:https://www.cnblogs.com/a736659557/p/11892371.html
Copyright © 2020-2023  润新知