python基础----函数作为返回值

从一个例子讲起

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。 还是考虑这个问题:对可变参数进行求和 看了上一讲的已经知道,可以使用’*’来表示接受一个tuple参数,代码大概可以这样写:

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
>> f = lazy_sum(1, 3, 2, 7, 9)
>> f
<function sum at 0x10452f668>

可以看到,我们返回的只是sum这个函数并没有返回函数计算得到的值 可以这样调用:

>> f()
>> 22

此时才是真正的计算出函数值;

闭包

我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”

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

f1()和f2()的调用结果互不影响;

注意: 返回的函数并没有立刻执行,而是直到调用了f()才执行,所以如果你的参数绑定的是循环变量,意味着你的变量值会随着迭代来改变,此时会出现你不想要的结果; 比如下面的例子:

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

f1, f2, f3 = count()

理论上应该返回1,4 ,9,但是结果是:

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

全是9,原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9; 返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

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

同时可以使用lambda函数缩短代码;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏流媒体

C++多态

当类存在虚函数时,编译器会为该类维护一个表,这个表就是虚函数表(vtbl),里面存放了该类虚函数的函数指针。在构造类的时候增加一个虚表指针(vptr)指向对应的...

1013
来自专栏十月梦想

运算符

=就是简单给变量的赋值,+(-,*,/,%,.)=等同于左边加上(减去,乘上,除以,求余数,字符连接)右边赋值给昨天

653
来自专栏小樱的经验随笔

【Java学习笔记之十】Java中循环语句foreach使用总结及foreach写法失效的问题

foreach语句使用总结 增强for(part1:part2){part3}; part2中是一个数组对象,或者是带有泛性的集合. part1定义了一...

2657
来自专栏北京马哥教育

一文搞懂 Python 正则表达式用法

1243
来自专栏前端学习心得

JavaScript基础(一)----强制转换与自动转换

JavaScript是一门动态语言,所谓的动态语言可以暂时理解为在语言中的一切内容都是不确定的。比如一个变量,这一时刻是个整型,下一时刻可能会变成字符串了。虽然...

862
来自专栏赵俊的Java专栏

Python 基础语法

1465
来自专栏Python小屋

Python内置函数sorted()从入门到精通

Python内置函数sorted()可以对列表、元组、字典、集合、字符串、range对象以及其他可迭代对象进行排序,返回排序后的列表,支持使用key参数指定排序...

26910
来自专栏WindCoder

《简明 Python 教程》学习笔记-运算符与表达式

又两天没更新了,暂且同步两篇之前的笔记。运算符与表达式这一块感觉主要就是运算符与它们的用法以及优先级了。

792
来自专栏我和PYTHON有个约会

10.程序编程基础4~变量&运算符

3.3 变量部分 3.4 运算符部分;主要讲解:赋值运算符、算数运算符、关系运算符、逻辑运算符、成员运算符、标识运算符

581
来自专栏步履前行

Java基础系列---操作符

  还记得我们刚开始学习Java的时候记住优先级和逻辑运算符就可以开始工作了,昨天在看到源码的时候发现一个操作符 |=,没有印象,然后去搜了下,发现提到的文章也...

1124

扫码关注云+社区