• 2、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,5)
    print f
    # <function sum at 0x02657770>
    # lazy_sum(1,2,3,4,5)返回的是一个指向求和的函数的函数名。
    # 在调用lazy_sum(1,2,3,4,5)的时候,不立刻求和,而是根据后面代码的需要在计算。
    print f()
    # 15
    # 用f()调用求和函数,计算出结果。
    
    f1 = lazy_sum(1,2,3,4,5,6)
    f2 = lazy_sum(1,2,3,4,5,6)
    print f1 == f2
    # False
    # lazy_sum()每调用一次,都会返回一个独一无二的函数地址。    

    例中,lazy_sum中的内部函数sum引用了外部函数lazy_sum的参数和局部变量,
    当lazy_sum返回函数sum时,相关参数和变量已经保存在返回的函数sum中了。
    我们称这为 闭包

    注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。

    另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。我们来看一个例子:

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

    结果全部都是9. 不是预期的1,4,9!

    遂在编辑器中不断更改并调试运行观察变量的变化过程:

    # -*- coding: utf-8 -*-
    
    def count():
        fs = []
        for i in range(1,4):
            def f():
                return i*i
            fs.append(f)
        return fs
    
    # f1, f2, f3 = count()
    #将上述代码分开写:
    f1 = count()
    f2 = count()
    f3 = count()
    
    print(f1())
    print(f2())
    print(f3())

    结果编译器报错:

    Traceback (most recent call last):
    File "***.py", line 16, in <module>
    print(f1())
    TypeError: 'list' object is not callable

    调试后发现原因:

    f1 = count()这条语句执行时,count()函数会先执行,并将结果fs(这是一个包含三个元素(值是三个不同函数)的list!)返还f1。所以f1()是将list当函数用,故报错!

    f2 = count()和f3 = count()也是这个道理。

    所以第一个要弄清楚的是 :初始代码中的f1, f2, f3 = count()是将count() 中返回值(list)的三个元素(元素值是函数)分别赋值给f1,f2,f3!此时它们是函数!

    修改代码:

    # -*- coding: utf-8 -*-
    
    def count():
        fs = []
        for i in range(1,4):
            def f():
                return i*i
            fs.append(f)
        return fs
    
    # f1, f2, f3 = count()
    f1 = count()
    f2 = count()
    f3 = count()
    
    print(f1[0]())
    print(f2[0]())
    print(f3[0]())

    结果仍然是:

    9

    9

    9

    调试后发现,运行f1[0]() 后:

     因为f1[0]()中存放的就是函数f, 但此时i是3,故返回输出9!

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

  • 相关阅读:
    《贝叶斯优化: 一种更好的超参数调优方式》
    《从Google Visor到Microsoft NNI再到Advisor调参服务接口发展史》
    《归一化激活层的进化:谷歌Quoc Le等人利用AutoML 技术发现新型ML模块》
    《通用视觉 & NAS》
    《Object Detection-IOU Net笔记》
    《Detectron2之ROIAlign》
    《IoUNet(6)_源码_RoIAlign(1)》
    聊天机器人资源合集:项目,语聊,论文,教程。
    一个使用 Python 的人工智能聊天机器人框架
    【TensorFlow 官网 可以直接访问】让中国开发者更容易地使用TensorFlow打造人工智能应用
  • 原文地址:https://www.cnblogs.com/zwb8848happy/p/8428517.html
Copyright © 2020-2023  润新知