一、閉包必須具備的條件
1、必須存在函數嵌套。
2、內部函數必須引用外部函數的變量。
3、內部函數必須不能引用全局變量。
4、外部函數的返回值必須是內部函數的函數名。
二、閉包的僞代碼格式
def 外層函數(參數):
def 內層函數():
print("內層函數執行", 參數)
return 內層函數
內層函數的引用 = 外層函數("傳入參數")
內層函數的引用()
三、閉包的簡單案例
def func1(a, b):
c=100
def inner_func():
s=a+b+c
print(s)
return inner_func
f=func1(1,2)
f()
#輸出結果:126
四、變量內存的釋放
通常情況下,當一個函數運行結束,函數內部的所有東西都會釋放掉,還給內存,函數的局部變量也會因此消失。然而,閉包是一種特殊情況,如果外部函數在結束時發現其變量會在內部函數中被使用,就會把這個變量綁定給內部函數,然後再結束自己的運行。
五、內部函數中修改外函數的值
上面講到,一般在函數結束時,會釋放臨時變量,但在閉包中,由於外函數的臨時變量在內函數中用到,此時外函數會把臨時變量與內函數綁定到一起,這樣雖然外函數結束了,但調用內函數時依舊能夠使用臨時變量,即閉包外層的參數可以在內存中進行保留
如果想要在內函數中修改外函數的值,需要使用 nonlocal 關鍵字聲明變量
def func1(a, b):
c=100
def inner_func():
nonlocal c
c+=23
s=a+b+c
print(s)
return inner_func
f=func1(1,2)
f()
#輸出結果:126
六、在內部函數中修改全局變量的值
則需要將全局變量聲明global在內部函數中
global_num=99
def func1(a, b):
c=100
def inner_func():
nonlocal c
global global_num
global_num+=33
c+=23
s=a+b+c+global_num
print(s)
return inner_func
f=func1(1,2)
f()
#輸出結果:258
七、閉包的作用
1、可以使用同級的作用域
2、讀取其他元素的內部變量
3、延長作用域
def func1(a, b):
c=10
def inn_fun():
s=a+b+c
print(s)
return inn_fun
ser=func1(6,9)
ser2=func1(2,8)
ser()
ser2()
#輸出結果:
#25
#20
八、閉包總結
1、閉包似乎優化了變量,原來需要類對象完成的工作,閉包也可以完成。
2、由於閉包引用了外部函數的局部變量,則外部函數的局部變量沒有及時釋放,消耗內存。
3、閉包的好處,使代碼變得簡潔,便於閱讀代碼。
4、閉包是理解裝飾器的基礎。