Python基础:函数式编程-返回函数与闭包

返回函数

函数作为返回值

返回函数每次调用都会返回一个新的函数,相关参数和变量都保存在返回的函数中。不需要立即计算,而是根据后面的代码根据需要再计算。

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax += n
        return ax
    return sum

f1 = lazy_sum(1,3,5,7,9)
f2 = lazy_sum(1,3,5,7,9)

print(f1())  # 加括号才算是调用,直接输出f1是个函数不是值
print(f1 == f2)

输出为25Falsef1()f2()的调用结果互不影响。

*args的用法

*args**kwargs 主要用于函数定义。 你可以将不定数量的参数传递给一个函数。这里的不定的意思是:预先并不知道, 函数使用者会传递多少个参数给你, 所以在这个场景下使用这两个关键字。 *args 是用来发送一个非键值对的可变数量的参数列表给一个函数.这里有个例子帮你理解这个概念:

def test_var_args(f_arg, *argv):
    print("first normal arg:", f_arg)
    for arg in argv:
        print("another arg through *argv:", arg)

test_var_args('yasoob', 'python', 'eggs', 'test')

这会产生如下输出:

first normal arg: yasoob
another arg through *argv: python
another arg through *argv: eggs
another arg through *argv: test

关于*argo的用法,摘抄自Blog。

闭包

相关参数和变量都保存在返回的函数中。

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i  # i并未和f绑定,这里i不是外层变量
        fs.append(f)  # f是函数,将f放到了list里面
    return fs

f1, f2, f3 = count()  
print(f1())
print(f2())
print(f3())

结果全部为9,需要注意的是,count()反回了一个由三个函数组成的list,f123分别对应来定义。返回的函数引用了变量i,但它并非立刻执行,也就是每个返回的函数里面还是i。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9。返回闭包时,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
另外,列表list默认是全局变量,变量在函数内部局部是局部变量,被global修饰的变量为全局变量, 而被nonlocal修饰的变量为外层函数局部变量(非全局变量)。

利用闭包返回计数器函数

def createCounter1():
    li = [0]  # 通过list全局变量实现
    def counter():
        li[0] += 1
        return li[0]  # 返回最后一个数
    return counter

def createCounter2():
    n = 0
    def counter():
        nonlocal n #通过nonlocal来使用外层函数的局部变量
        n += 1
        return n
    return counter

counterA = createCounter2()
print(counterA(),counterA(),counterA())  # 每一次调用,list是不断变长的

你可能感兴趣的:(Python基础:函数式编程-返回函数与闭包)