美文网首页
廖雪峰 | 5.1 返回函数和匿名函数

廖雪峰 | 5.1 返回函数和匿名函数

作者: 苦哈哈的柠檬水 | 来源:发表于2022-04-19 22:32 被阅读0次

    返回函数

    1,实例1:可变参数求和
    (1)即时返回求和结果

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

    (2)返回求和函数,调用该函数则得结果

    def lazy_sum(*args):
        def sum():
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum
    #调用lazy_sum()函数
    >>> f = lazy_sum(1, 3, 5, 7, 9)
    >>> f
    <function lazy_sum.<locals>.sum at 0x101c6ed90>
    #调用f()函数,得求和结果
    >>> f()
    25
    
    • 在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种程序称为“闭包(Closure)”
    • 调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数,结果函数也不相同
    >>> f1 = lazy_sum(1, 3, 5, 7, 9)
    >>> f2 = lazy_sum(1, 3, 5, 7, 9)
    >>> f1==f2
    False
    >>> f1()
    25
    >>> f2()
    25
    

    2,实例2(闭包):依次返回1,2,3的平方数值

    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
    

    3,实例3(nonlocal):返回递增整数的计数器函数
    (1)如果只是读外层变量的值,返回的闭包函数调用一切正常:

    def inc():
        x = 0
        def fn():
            # 仅读取x的值:
            return x + 1
        return fn
    
    f = inc()
    print(f()) # 1
    print(f()) # 1
    

    (2)如果对外层变量赋值,由于Python解释器会把x当作函数fn()的局部变量,它会报错:

    def inc():
        x = 0
        def fn():
            # nonlocal x
            x = x + 1
            return x
        return fn
    
    f = inc()
    print(f()) # 1
    print(f()) # 2
    

    原因是x作为局部变量并没有初始化,直接计算x+1是不行的。但我们其实是想引用inc()函数内部的x,所以需要在fn()函数内部加一个nonlocal x的声明。加上这个声明后,解释器把fn()x看作外层函数的局部变量,它已经被初始化了,可以正确计算x+1

    • 使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
      (3)练习:利用闭包返回一个计数器函数,每次调用它返回递增整数:
    # -*- coding: utf-8 -*-
    def inc():
        x = 0
        def fn():
            nonlocal x
            x = x + 1
            return x
        return fn
    
    # 测试:
    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('测试失败!')
    

    匿名函数

    1,匿名函数:lambda表示

    • 关键字lambda表示匿名函数,冒号前面的x表示函数参数
    • 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果
    • 匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
    • 可以把匿名函数作为返回值返回
    >>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    [1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    >>> f = lambda x: x * x
    >>> f
    <function <lambda> at 0x101c6ef28>
    >>> f(5)
    25
    
    def build(x, y):
        return lambda: x * x + y * y
    

    2,练习
    问:请用匿名函数改造下面的代码:

    # -*- coding: utf-8 -*-
    def is_odd(n):
        return n % 2 == 1
    
    L = list(filter(is_odd, range(1, 20)))
    
    #改造后
    L = list(filter(lambda n: n%2 == 1, range(1, 20)))
    print(L)
    

    相关文章

      网友评论

          本文标题:廖雪峰 | 5.1 返回函数和匿名函数

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