python的返回函数和匿名函数

笔记源于廖老师的教程

1、返回函数

python的高阶函数不仅可以把函数当成参数传入,也可以返回函数。当我们此时不需要计算,但是在后面的代码中需要计算的时候,就可以使用返回函数。
举例:求和

>>> def lazy_sum(*args):
...     def sum():
...         ax = 0
...         for n in args:
...             ax = ax + n
...         return ax
...     return sum #返回求和函数
...
>>> f = lazy_sum(1, 2, 3, 4) #当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数
>>> f
<function lazy_sum.<locals>.sum at 0x00000000026E8730>
>>> f() #调用函数的时候,才执行计算
10
>>>

闭包:

在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值还引用了内函数的引用。这样就构成了一个闭包。
闭包使用不当会出现下面的问题,举例:

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

f1, f2, f3 = count() # count()返回的是三个函数此处相当于: f1, f2, f3 = [f, f, f], 

你可能会以为逐个调用结果是:f1() = 1, f2() = 4, f3() = 9
但结果是:

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

为什么三个函数的计算的值都是9呢?
我们先把上面的代码改一下

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

return i 的时候for循环已经写入三次,所以最后i的值是3;同理fs.append(f)的时候,只是把内部函数加入list, 但并没有立刻执行i的计算,当return fs的时候,开始执行计算,而此时i已经是循环变量i的值已经是3, 所以f1()、f2()、f3()的值都是9。

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

如果一定要使用循环变量,可以在内部再定义一个函数,绑定当前循环变量

>>> def count():
...     def f(j):
...         def g():
...             return j*j
...         return g
...     fs = []
...     for i in range(1, 4):
...         fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
...     return fs
...
>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
>>>

2、匿名函数

有些时候我们不想定义一个显示函数,就可以定义一个匿名函数,不仅方便也可以避免函数名的冲突。
举例:先不使用匿名函数

>>> def f(x):
...     return x * x
...
>>> list(map(f, [1, 2, 3, 4]))
[1, 4, 9, 16]

上面的

>>> def f(x):
...     return x * x
...

用匿名函数表示是:lambda x : x * x
解释:第一个x就是传入的参数, 冒号‘:’后面的 x * x 表达式就是返回的结果

>>> list(map(lambda x : x * x, [1, 2, 3, 4]))
[1, 4, 9, 16]

匿名函数可以用变量去接收,可以通过变量来调用:

>>> f = lambda x : x * x
>>> f
<function <lambda> at 0x00000000026E8730>
>>> f(2)
4
>>>

猜你喜欢

转载自blog.csdn.net/qq_29144091/article/details/81333011