廖雪峰_返回函数_闭包例子fs.append(f)、练习及意义详解

廖雪峰_返回函数_闭包 示例:

注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。

另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

    def count():
        fs = []
        for i in range(1, 4):
            def f():
                 return i*i
            fs.append(f)
        return fs

f1, f2, f3 = count()    #此时count返回的fs=[f,f,f](三个f是互不相等的,内存位置不同),于是赋值f1=f,f2=f,f3=f,此时i=3.

在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了。

你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

>>> f1()
9
>>> f2()
9
>>> f3()
9

全部都是9!原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

练习

利用闭包返回一个计数器函数,每次调用它返回递增整数:

# -*- coding: utf-8 -*-

def createCounter():
    i=[0]    #i=0是错误的,整型是不可变量,列表可变。
    def counter():
        i[0]=i[0]+1 
        return i[0]

    return counter

# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')

Run
1 2 3 4 5
测试通过!

意义:
转载:[Python小记] 通俗的理解闭包 闭包能帮我们做什么?

猜你喜欢

转载自blog.csdn.net/richand112233/article/details/88317168