美文网首页
返回函数(第28篇)

返回函数(第28篇)

作者: 你好星期四 | 来源:发表于2016-04-13 19:33 被阅读46次

    一个函数可以返回一个函数。
    举个例子:

    def func_a(x, y):
        def func_b():
            return x + y
    
        return func_b
    

    在func_a函数中定义了一个函数func_b,最后将func_b返回。
    当我们调用func_a的时候,返回的并不是x与y的和,而是func_b:

    >>> f = func_a(1,2)
    >>> f
    <function func_a.<locals>.func_b at 0x1013d9950>
    

    接着调用func_a返回的函数:

    >>> f()
    3
    

    闭包

    上面的例子中,func_b是定义在func_a中的。func_b可以使用func_a中的参数和局部变量。

    如果func_a中没有定义func_b,那么当func_a调用结束后,func_a中的参数和局部变量都将被释放。但现在,func_a中还有一个func_b,并且func_b还使用了func_a中的参数和局部变量(但在这个例子中,func_a没有局部变量)。那么当func_a调用结束后,func_a中的参数和局部变量将不会被释放,而是保存在了func_b中。

    这就是闭包。

    每次调用func_a的时候返回的都是一个新的函数对象。彼此互不干扰,互不相等。

    函数中返回的函数并没有立刻执行

    这是比较容易弄混的一个地方。当一个函数被返回的时候,他并没有立刻执行,而是等到你调用它的时候它才执行。
    是不是感觉有点废话?那么来看看下面这个例子:

    def count():
     L = []
     for i in range(4):
     def func():
     return i
     L.append(func)
     return L  
    
    i1, i2, i3 = count()    
    

    你知道i1(),i2(),i3()分别等于什么吗?
    你可能会认为i1()为1,i2()为2,i3()为3。但事实却是:

    >>> i1()
    3
    >>> i2()
    3
    >>> i3()
    3
    

    因为i1,i2,i3三个函数都引用了变量i,但它们没有立刻执行,而是在你调用它们的时候才执行,而你调用它们的时候,i 已经变成了3。

    返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

    如果一定要引用循环变量,你可以再创建一个函数。用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

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

    再来看看

    >>> i1,i2,i3 = count()
    >>> i1()
    1
    >>> i2()
    2
    >>> i3()
    3
    

    相关文章

      网友评论

          本文标题:返回函数(第28篇)

          本文链接:https://www.haomeiwen.com/subject/bofglttx.html