本人最近在学习闭包,动手写了一个计算移动平均的高阶函数,但是在输出的时候和自己的预期有出入,错误代码如下:
def averager():
sum = 0
n = 0
def avg(i):
nonlocal sum, n
sum += i
n += 1
return print(sum/n)
return avg
a=averager()(3)
a=averager()(5)
a=averager()(7)
我知道代码错在:
a=averager()(3)
a=averager()(5)
a=averager()(7)
因为改成:
a=averager()
a(3)
a(5)
a(7)
就能够正确的计算移动平均值了,正确的输出分别是 3, 4, 5。
然后问题来了,我想请教两个问题;
- 我的错误代码错在哪里?
- 我看到正确代码中闭包对于传入的 3, 5, 7 都会存到
sum
和n
两个自由变量中,这个存储的机制可以帮我解释一下吗?
感激不尽!
python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量
nonlocal sum,n
声明直接引用外层作用域变量,也就是内层函数avg()之外,averager()中的两个变量.这样执行
a = averager()
就相当于初始化了sum
和n
,之后调用a(3), a(5), a(7)
因为sum, n
直接从外层作用域调用,所以值进行了累加.而如果每次都执行
a = averager()(n)
就相当于每次都对'sum, n'进行了一遍初始化