def foo(x): def bar(y): return x + y return bar if __name__ == "__main__": f = foo(1) f(100) # output # >>>101
eg.1
#!/usr/bin/python # -*- coding: utf-8 -*- def make_averager(): series = [] # 自由变量 def averager(new_value): series.append(new_value) # 访问外层函数的自由变量 total = sum(series) return total/len(series) return averager if __name__ == "__main__": avg = make_averager() print(avg(10)) print(avg(11)) print(avg(12))
optimized.
#!/usr/bin/python # -*- coding: utf-8 -*- """
上面的例子需要在函数中保存整个序列,比较低效并且耗费资源,可以只保存总和和个数
""" def make_averager(): """ version for python 2 :return: """ # 如果sum_all是数字等不可变对象,在内层函数sum_all进行更新时 # 实际上会创建一个新的局部变量然后赋值,这个时候sum_all就不是自由变量了, # 内层函数也就无法访问,count同理 sum_all = [0] count = [0] def averager(new_value): sum_all[0] += new_value count[0] += 1 return sum_all[0]/count[0] return averager def make_averager_1(): """ version for python 3 :return: """ sum_all = 0 count = 0 def averager(new_value): # nonlocal关键字指明sum_all和count不是局部变量, # 将其标记为自由变量,这样就可以在内层函数中进行更新。 nonlocal sum_all, count sum_all += new_value count += 1 return sum_all/count return averager if __name__ == "__main__": avg = make_averager() print(avg(10)) print(avg(11)) print(avg(12)) avg1 = make_averager_1() print(avg1(10)) print(avg1(11)) print(avg1(12))
https://stackoverflow.com/questions/739654/how-to-make-function-decorators-and-chain-them-together
闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样当调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定(《流畅的python》)。
通俗一点,闭包就是在一个函数(foo)里面定义了另一个函数(bar),定义在函数内部的这个函数(bar)引用了外部作用域(定义它的函数foo)的变量(自由变量x)。
闭包:内层函数访问外层函数的变量。
装饰器:函数的函数,高阶函数。