1:闭包的定义
首先看下面代码:
def outer(): x = 100 def inner(): print(x) return inner ret = outer()ret() """输出:100"""
在上面代码中,对ret的调用本质上是运行了outer运行时,里面创建的inner函数;这能行得通是因为Python中函数和其他一切一样都是对象,所以函数可以作为其他函数的返回值传递回来。更重要的是里面的函数inner记住了外层函数outer中的局部变量x,尽管外层函数outer已经不处于激活状态。
这种代码行为我们称之为闭包,或者叫工厂函数。其特点是它能够记住外层作用域中的值,不管那些嵌套作用域是否还在内存中。
其写法为:在外层函数中声明一个变量. 在内层函数使用或者返回这个变量。
2:闭包的作用
a:记忆外层作用域中的值;
b:可以保护变量不被修改;
c:可以让一个变量常驻内存;
def outer(): x = 100 def inner(): print(x) return inner # print(outer.x) # AttributeError: 'function' object has no attribute 'x'outer.x = 300print(outer.x) action = outer()action() print(outer.x) """输出:300100300
3:一简单的工厂函数(闭包)
def outer(N): def inner(X): return X**N return inner f2 = outer(2)print(f2(2)) # 2 ** 2print(f2(3)) # 3 ** 2print(f2(4)) # 4 ** 2 f3 = outer(3)print(f3(2)) # 2 ** 3print(f3(3)) # 3 ** 3print(f3(4)) # 4 ** 3
4:使用 nonlocal 修改外层作用域中的变量
不能修改外层作用域中的变量(如下):
def outer(start): cnt = start def inner(lable): print(lable,cnt) # cnt += 1 # 不能修改外层作用域中的变量 return inner f1 = outer(10)f1('f1')f1('f1') f2 = outer(10)f2('f2')f2('f2') """f1 10f1 10f2 10f2 10"""
使用nonlocal :
def outer(start): cnt = start def inner(lable): nonlocal cnt print(lable,cnt) cnt += 1 return inner f1 = outer(10)f1('f1')f1('f1') f2 = outer(10)f2('f2')f2('f2') f3 = outer(100)f3('f3')f3('f3') f1('f1')f2('f2')f3('f3') """# cnt 在f1,f2,f3中是独立的f1 10f1 11f2 10f2 11f3 100f3 101f1 12f2 12f3 102"""
领取专属 10元无门槛券
私享最新 技术干货