zoukankan      html  css  js  c++  java
  • 11-生成器

    一、如何得到自定义的迭代器(生成器)

    在函数内一旦存在yield关键字,调用函数并不会执行函数体代码

    会返回一个生成器对象,生成器即自定义的迭代器

    def func():
        print('第一次')
        yield 1
        print('第二次')
        yield 2
        print('第三次')
        yield 3
        print('第四次')
    
    
    g=func()              # 此时并不运行函数体代码
    print(g)              # <generator object func at 0x000001D009181740>
    # 生成器就是迭代器
    # g.__iter__()          均可调用
    # g.__next__()
    
    # next()或g.__next__ 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值
    # 当做本次调用的结果返回
    res1=g.__next__()             # 打印第一次
    print(res1)                   # 1
    
    res2=g.__next__()             # 打印第二次
    print(res2)                   # 2
    
    res3=g.__next__()             # 打印第三次
    print(res3)                   # 3
    
    res4=g.__next__()             # 打印第四次,并抛出异常StopIteration

    二、应用案例

    def my_range(start,end=None,step=1):
    
        # 满足 range(5)---》0 1 2 3 4 的情况
        if end is None:
            output = 0
            while output < start:
                yield output
                output += step
        else:
    
        # 满足 range(0,5,2) 设定步长输出
            if step > 0:
                while start < end:
                    yield start
                    start += step
    
        # 满足range(5,0,-1) 步长为负时,逆走
            if step < 0:
                while start > end:
                    yield start
                    start += step

    测试:

    # 测试:
    for i in my_range(5,0,-2):
        print(i,end=" ")
    
    print("")
    
    for i in range(5,0,-2):
        print(i,end=" ")

    三、yield表达式 

    3.1 yield表达式介绍

    一般形式:x = yield 返回值

    使用 g.send(“xxx”)的方式给x传参,并且send在传参后自带next()功能

    但一个生成器开始时,需要进行初始化(g.send(None) 或 next(g))。若不初始化,将会有以下报错:

      

     3.2 yield表达式的使用案例

    def dog(name):
        food_list=[]
        print('道哥%s准备吃东西啦...' %name)
        while True:
            # x拿到的是yield接收到的值
            x = yield food_list # x = '肉包子'
            print('道哥%s吃了 %s' %(name,x))
            food_list.append(x) # ['一根骨头','肉包子']
    
    g=dog('alex')
    res=g.send(None)  # next(g)
    print(res)        # []
    
    res=g.send('一根骨头')
    print(res)        # ['一根骨头']
    
    res=g.send('肉包子')
    print(res)       # ['一根骨头', '肉包子']
    
    g.close()
    g.send('1111')  # 关闭之后无法传值 StopIteration

    四、总结yield

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

    有了yield表达式,我们可以使函数的运行状态挂起,随时待命,等待我们再次传值给他。
  • 相关阅读:
    Fidder
    常见正则表达式使用
    HTML5 Boilerplate
    微信公众号开发--微信机器人
    sublime text插件推荐
    个人博客开发-笔记
    css之图像替换
    关于浮动与清除浮动
    css定位机制
    Java 集合类实现原理
  • 原文地址:https://www.cnblogs.com/zhubincheng/p/12562447.html
Copyright © 2011-2022 走看看