Python闭包输出问题

本人最近在学习闭包,动手写了一个计算移动平均的高阶函数,但是在输出的时候和自己的预期有出入,错误代码如下:

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。

然后问题来了,我想请教两个问题;

  1. 我的错误代码错在哪里?
  2. 我看到正确代码中闭包对于传入的 3, 5, 7 都会存到 sumn 两个自由变量中,这个存储的机制可以帮我解释一下吗?

感激不尽!

阅读 1.8k
1 个回答

python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量
nonlocal sum,n声明直接引用外层作用域变量,也就是内层函数avg()之外,averager()中的两个变量.
这样执行a = averager()就相当于初始化了sumn,之后调用a(3), a(5), a(7)因为sum, n直接从外层作用域调用,所以值进行了累加.
而如果每次都执行a = averager()(n)就相当于每次都对'sum, n'进行了一遍初始化

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题