2、Python 函数作为返回值 - Go语言中文社区

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!

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

posted on 2018-02-07 21:38 Hello _ world 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/zwb8848happy/p/8428517.html

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_34331102/article/details/94757072
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 10:47:04
  • 阅读 ( 1539 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢