Python教程学习简记9--Python 返回函数 闭包

来源:互联网 发布:mac查找文件路径 编辑:程序博客网 时间:2024/05/28 04:55

函数作为返回值

高阶函数除了可以接收函数作为参数外,还可以把函数作为结果值返回。

我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:

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)print(f)

这里写图片描述

调用函数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)print(f1 == f2)

这里写图片描述
f1()和f2的调用结果互不影响。

闭包

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

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

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

在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回来了。

调用f1() f2() f3():结果如下

print(f1())print(f2())print(f3())

这里写图片描述

结果全部都是9,原因就在于返回的函数引用了变量i,但它并非立即执行。
等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9.

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

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

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 fsf1, f2, f3 = count()print(f1())print(f2())print(f3())

这里写图片描述

缺点是代码较长,可利用lambda函数缩短代码。

小结:

一个函数可以返回一个计算结果,也可以返回一个函数。

返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老婆是个越南人至今没户口怎么办 等离子屏z板链接处排线打火怎么办 等离子自动调焊的成形不好怎么办 村里内村道路中间被抢占了怎么办 华为换电池之后卡没反应怎么办 汽车钥匙换电池后没反应怎么办 汽车解锁换电池后没反应怎么办 包裹显示待收件人向海关申报怎么办 在越南签证被公安扣了怎么办 酷派手机收不到验证码怎么办 苹果想把图片上的字盖上怎么办 婴儿自己把眼珠子抠红了怎么办 如果美陆战队员进入台湾那怎么办? 顺产生完小孩吸不通奶怎么办 耐克空军一号白色底发黄怎么办 中行网银u盾丢了怎么办 有人用你的手机号码不停注册怎么办 获得公开你微信头像的权限是怎么办 手机能进的网站电脑进不去怎么办 苹果8p下不了微信怎么办 苹果手机版本过底不能下微信怎么办 手机打开视频跳转到qq是怎么办 淘宝店铺显示服务竟然出错了怎么办 母羊下完羊羔把羊衣吃了怎么办? 移植后56天有黑色东西怎么办 我家的金丝熊浑身都是尿怎么办 一键启动车钥匙丢了怎么办 把爷爷的遗物弄丢了怎么办 如果你娶了一个傻子你怎么办 在国外订机票手机收不到信息怎么办 网上买机票名字写错了怎么办 买机票名字错了一个字怎么办 微店没收到货却显示已收货怎么办? 手机存的照片误删了怎么办 魔兽世界把要用的装备分解了怎么办 邻居家的狗见到我就叫怎么办 我的世界玩的时间长会卡应该怎么办 网易我的世界密码账号都忘了怎么办 我的世界创建世界画面乱码了怎么办 网易我的世界云端存档不够用怎么办 玩刺激战场带耳机声音有延迟怎么办