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())
  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/LS1314/p/8504539.html
Copyright © 2011-2022 走看看