zoukankan      html  css  js  c++  java
  • 闭包, 迭代器, 生成器

    一 闭包

    1. 在嵌套函数内,内部函数使用外部非全局变量
    2. 作用:保护数据的安全性
    3. 装饰器的本质就是闭包
    def func():
        avg_lst = []  # 自由变量
        def foo(pirce):
            avg_lst.append(pirce)
            avg = sum(avg_lst) / len(avg_lst)
            return avg
        return foo
    ret = func()
    print(ret(150000))
    print(ret.__closure__) # 查询是不是闭包
    print(ret.__code__.co_freevars) # 获取的是自由变量
    print(ret.__code__.co_varnames) # 获取的是局部变量
    

    二 迭代器

    ###2.1 可迭代对象
    查看 dir()

    内部含有__iter__方法的对象,都是可迭代对象。
    

    优点:使用灵活,可以直接查看值

    缺点:占内存,不能迭代取值

    ###2.2 迭代器

    只要具有__iter__()方法__next__()方法就是迭代器
    

    优点:节省内存,内存机制

    缺点:使用不灵活,操作比较繁琐,不能直接查看元素

    特点:一次性的(用完就没了),不可逆性(不可后退),惰性机制

    ###2.3 将可迭代对象转换成迭代器

    lst = [1,2,3,4,6]
    new_list = lst.__iter__()  #将可迭代对象转换成迭代器
    

    ###2.4 for 循环的本质

    lst = [1,2,3,4,5,6,7,8,9]
    new_lst = lst.__iter__()    #先转换成迭代器
    while 1:
        try:
            print(new_lst.__next__())
        except StopIteration:
            break
    

    三 生成器

    生成器本质就是迭代器,和迭代器不同的是,迭代器是python内置的,生成器是自己用代码构建的

    3.1 生成器的构建方式

    1. 通过自己写的生成器函数
    2. 通过生成器推导式
    3. python内置函数或者模块提供

    3.2 生成器函数

    ####1. yield

    将函数中的return换成yield,这样func就不是函数了,而是一个生成器函数

    def func():
        print(11)
        yield 22
    ret = func()   #产生一个生成器
    print(ret)
    

    输出结果:<generator object func at 0x000000000223FE08>

    当我们调用函数的时候函数体里的代码会进行执行当执行到yield的关键字的时候,发现我们是想声明一个生成器.程序就会返回一个生成器给咱们

    生成器取值和迭代器一样

    def func():
        print("111")
        yield 222
        print("333")
        yield 444
    gener = func()
    ret = gener.__next__()
    print(ret)
    ret2 = gener.__next__()
    print(ret2)
    ret3 = gener.__next__()
    # 最后一个yield执行完毕,再次__next__()程序报错
    print(ret3)
    

    生成器函数中可以写多个yield,当程序运行完最后一个yield,那么后面继续运行next()程序会报错,一个yield对应一个next,next超过yield数量,就会报错,与迭代器一样。

    print(func().__next__()) # 坑 -- 会产生新的生成器
    print(func().__next__())
    

    yield与return的区别:

    return一般在函数中只设置一个,他的作用是终止函数,并且给函数的执行者返回值。

    yield在生成器函数中可设置多个,他并不会终止函数,next会获取对应yield生成的元素。yield会记录执行位置,在函数内部yield能将for和while循环临时暂停

    ####2. seed

    def gen(name):
        print(f'{name} ready to eat')
        while 1:
            food = yield
            print(f'{name} start to eat {food}')
    dog = gen('alex')
    next(dog)
    dog.send('骨头') # 还可以给上一个yield发送值
    dog.send('狗粮')
    dog.send('香肠')
    

    send和next()区别:

    相同点:

    send 和 next()都可以让生成器对应的yield向下执行一次。

    都可以获取到yield生成的值。

    不同点:

    第一次获取yield值只能用next不能用send(可以用send(None))。

    send可以给上一个yield置传递值.

    ####3. yield from (python3中) 将可迭代对象元素逐个返回

    def func():
        lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
        lst2 = ['馒头', '花卷', '豆包', '大饼']
        yield from lst1
        yield from lst2
    g = func()
    for i in g:
        print(i)
    

    将第一个列表的元素全部返回后,再返回第二个列表

  • 相关阅读:
    SQVI和SAP查询QUERY的区别和使用注意事项
    hdu 4119 Isabella's Message
    HaProxy+Keepalived+Mycat高可用群集配置
    Android之RecyclerView简单使用(三)
    2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效
    怎样cp文件夹时忽略指定的文件夹和文件
    使用boost::property_tree生成带attribute的xml
    数据结构:中序线索二叉树
    像音乐播放App一样移动背景
    【EasyUi】页面设计必学之Layout
  • 原文地址:https://www.cnblogs.com/lav3nder/p/11801564.html
Copyright © 2011-2022 走看看