zoukankan      html  css  js  c++  java
  • 返回函数

    正常的函数如下所示:

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

    但如果函数返回值是一个函数,示例如下:

    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>
    

     可以看出直接调用lazy_sum(1,3,5,7,9)只会返回求和函数sum,但是返回的函数中又包含了调用时的参数、变量,如1,3,5,7,9,因此使用f()调用时得到25的结果,这种结构称为闭包。对于内部函数而言,引用了外层函数的变量,这种就属于闭包。

    >>> f()
    25
    

    其实也可以有办法立即执行,因为return返回了f2(),而不是f2,如下例:

    def f1(x):
    k=200
    def f2():
    nonlocal x,k
    x*=x
    k*=k
    print('k'+str(k))#输出40000  
    print('x'+str(x))#输出10000
    f2()
    print('k'+str(k))#输出40000
    print('x'+str(x))#输出10000
    f1(100)

    上例还展示了一种情况,内部函数试图改变闭包函数的变量值,但是这种做法是不被允许的,会报错,但是上例中使用了nonlocal关键字,定义了与闭包函数的变量同名的两个变量(x,k均为闭包变量),因此在内部函数作用域内可以对这两个值进行改变,在闭包作用域中,这两个值也发生了改变。

    输出如下:

    k200
    x100
    10000 40000

    返回函数不仅可以引用外部函数的参数,而且还可以引用外部函数内部定义的局部变量,因此如果返回函数中引用的变量发生变化,会导致出问题,如下例所示:

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

     该例返回了一个函数列表,含有三个函数,调用时因为返回的函数并没有立即执行,而是等到调用了f()才执行,所以实际结果是   

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

    就是因为等三个函数都返回时,闭包变量i变成了3,所以最终结果都是9,因此返回函数不能引用任何后续会发生变化的变量。

    如果一定要引用循环变量,那么需要再创建一个函数A,循环变量放在该函数A的外围,用循环变量作为该函数A的参数,而该函数A内部返回函数B,引用函数A的参数,此时因为外部循环得到的值是通过参数输入到函数A中,该参数已经固定,不会变化。

      

     

      

  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/vonkimi/p/6901042.html
Copyright © 2011-2022 走看看