返回函数

本文通过实例解析Python中的闭包概念及其工作原理,包括变量的作用域、闭包如何保留外部函数变量等问题,并提供了两种解决闭包中变量修改问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

n = 0
def createcounter():
    def counter():
        global n
        n = n + 1
        return n
    return counter

f1 = createcounter()
print(f1(),f1(),f1())  #连续调用createcountter时,n没有被释放,而是被下一次调用所使用
print(f1())
print(f1())

转载至廖老师教程里的讨论这章比较难理解,反复学习加上网友的讨论,还有看了其他一些补充资料,总结以下理解这一课的几个知识点(非行内人士,不够专业请谅解):

1、f1, f2, f3 = count() 这种赋值的右边是一个tuple,所以f1 = fs[0]、f2 = fs[1]、f3 = fs[2]

2、闭包closure的主要特征就是内部函数调用了外部函数的变量,不过内部函数只能调用,不能修改

3、外部函数在结束的时候,通常情况下会释放变量,但是在闭包中由于变量被内部函数调用了,打个比方,外部函数在准备放人(变量)的时候发现内部函数还在用人(变量),所以就没有释放销毁变量

4、所谓的返回函数,其实只是返回了函数的名(或者地址门牌之类的),并没有去执行函数的内容(例如函数的变量的值等等)。这个体现为代码就是本章的第一个例子中的 f = lazy_sum(1, 3, 5, 7, 9)

5、至于什么时候才真正看返回的函数的变量?这个就要等到执行函数的时候,体现为代码就是加个小括号,例如 f()

6、上面的2、3、4、5点加起来,就是为什么本章的 f1()、f2()、f3()一开始的运行结果都是9的原因了:首先,内部函数f() 可以调用外部函数count()的变量i,这个就是第2点里面说的意思;其次,f1, f2, f3 = count(),实际上只调用了“一次”外部函数count(),只不过count()返回的是一个List列表fs,而这个List列表fs里面有三个元素都是函数f(),不过要注意的是,虽然都叫f(),但实际上在内存里面是分了“三块地方(地址)”来存放的,实际上是“三个”都叫f()的函数。再次,在调用了“一次”外部函数count()产生了一个列表List(元素分别是三个都叫f()的函数)以后,本来是准备打算释放变量i的,但是由于闭包的存在,所以到最后并没有释放 i(也就是第3点的意思)。最后,高潮问题来了,虽然 i 没有被释放,但是在调用count()产生列表的时候,又并未真正执行里面的内容f(),仅仅是把三个f()的地址分别赋予了f1、f2、f3。可是在产生这三个f()的时候,i 却已经从 1 执行到 3 了,所以等到真正执行f()的时候(此时f加了个小括号),才执行里面的i*i,所以,最后三个函数的结果都是3乘以3,也就是9了。

7、至于作业,有两个方法:一个是用nonlocal声明,这个是从python3开始有的;另一个就是用可变对象,这里重点说一下用可变对象,我的理解应该是其实这是一个取巧的方法,实际上并没有改变内部函数只能调用不能改变外部函数的变量这个特征,只不过由于外部函数的变量是一个List,而List的内容是可变的,所以取巧实现了目的,事实上外部函数的变量至始至终都是指向了一个List,而内部函数只不过是让List的元素内容发生变化而已。

以上均为非专业的理解,说的不对请指正。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值