zoukankan      html  css  js  c++  java
  • 30-高级特性之闭包(2)

    1. inner_sum便是一个闭包,他的生命周期和自由变量args一样。

    def calc_sum(*args): #可变参数
        def inner_sum():
            ix = 0 #局部变量,暂存累加结果
            for y in args:   #args是calc_sum这个外部函数的变量, 被内部函数{闭包}inner_sum使用了,故args为自由变量
                ix += y
            return ix
        return inner_sum
    f = calc_sum(1,2,3,4,5) #此时仅仅返回了inner_sum(), 但并没有激发inner_sum()
    print(f,'
    ') 
    res = f()    #调用才激发,懒惰函数
    print(res, '
    ')
    

    2. 每次调用主调函数返回的inner_sum()都是完全不同的,哪怕传入实参相同

    f1 = calc_sum(1,2,3,4,5)
    f2 = calc_sum(1,2,3,4,5)
    print(f1==f2,'
    ')
    

    3. 注意:因为外部函数返回一个内部函数时,该内部函数并未执行。所以内部函数中不要引用任何可能会变化的变量。

    #比如,下面“诡异的异常结果”
    def count():
        fs = []
        for i in range(1,4): #[1,4)
            def f():
                return i*i
            fs.append(f)   #把三个f都装入fs,待会儿返回出去
        return fs
    f1,f2,f3 = count()
    print(f1(), f2(),f3(), '
    ') #i最终为3,结果三个f()激发的时候都是3*3
    
    #4.防止发生上述的错误,加一层g,并把g(i)绑定for循环的i
    def count_2():
        def g(i):                #g是外部函数,不能存在延迟激发
            def f():         #f是内部函数{闭包},会被延迟激发
                return i*i
            return f     #此时返回f,f为闭包
        fs = []
        for i in range(1,4):
            fs.append(g(i))   #g(i)相比较f()而言,为外部函数,立刻执行激发,故把当前的i带入f()
        return fs             #fs压入3个g,相比cout_2而言,g是闭包,g在count_2()时还不会激发
    g1,g2,g3 = count_2()
    print(g1,'
    ',g2,'
    ',g3,'
    ')
    print(g1(), g2(), g3(), '
    ') #此刻g被激发执行,带动f被激发执行
    

    4. 作业:闭包返回一个计数器

    def f():             #f仅仅用来产生递增数据流,可移动至CreateCounter外部,也可以移进去
            n = 1
            while True:
                yield n
                n += 1
    def CreateCounter():
        it = f()             #立刻调用f这个generator,f已经产生了所有的递增序列it
        def counter():       #通过counter每次返回it的一个项
            return next(it)   #每次调用只返回it中的一个元素,故而next
        return counter        #把counter返回出去
    CountA = CreateCounter() #返回一个counter,但counter没有被激发
    print(CountA,'
    ')
    
    for i in range(5): #5次调用CountA,即每次都激发一下counter,而激发counter的结果就是:next(it),即取一个数
        print(CountA())
  • 相关阅读:
    最大子数组
    链表插入排序
    链表求和
    有效回文串
    排球比赛计分系统
    超市收银系统
    三层架构
    Wpf+数据库代码封装+策略模式封装
    封装逻辑用策略模式实现
    代码封装
  • 原文地址:https://www.cnblogs.com/LS1314/p/8504539.html
Copyright © 2011-2022 走看看