在函數(shù)內(nèi)部再定義一個(gè)函數(shù),并且這個(gè)函數(shù)用到了外邊函數(shù)的變量,那么將這個(gè)函數(shù)以及用到的一些變量稱之為閉包。在了解閉包之前,先了解一下函數(shù)的引用。
def test():
print('...test...')
test()
t1 = test
t1()
print(id(test))
print(id(t1))
print('*'*15)
結(jié)果如下:

函數(shù)的引用.jpg
那閉包是如何在函數(shù)內(nèi)引用函數(shù)的?看如下代碼:
def test(number):
def test_in(number_in):
print('test_in的number_in是:%s'%number_in)
return number+number_in
return test_in
t1 = test(10)
print(t1(20))
print(t1(30))
結(jié)果如下:

閉包.jpg
接下來看一個(gè)閉包的實(shí)際例子,定義一個(gè)函數(shù)曲線,給定x的值求y的值。
def fun1(k,b):
def fun1_in(x):
print('x的值是:%s'%x)
return k*x+b
return fun1_in
f1 = fun1(2,1)
print(f1(3))
結(jié)果如下:

閉包實(shí)例.jpg
這個(gè)例子中,函數(shù)fun1與變量k,b構(gòu)成閉包。在創(chuàng)建閉包的時(shí)候,我們通過fun1的參數(shù)k,b說明了這兩個(gè)變量的取值,這樣,我們就確定了函數(shù)的最終形式(y=kx+b)。我們只需要變換參數(shù)a,b,就可以獲得不同的直線表達(dá)函數(shù)。由此,我們可以看到,閉包也具有提高代碼可復(fù)用性的作用。
如果沒有閉包,我們需要每次創(chuàng)建直線函數(shù)的時(shí)候同時(shí)說明k,b,x。這樣,我們就需要更多的參數(shù)傳遞,也減少了代碼的可移植性。
閉包似優(yōu)化了變量,原來需要類對象完成的工作,閉包也可以完成。
但由于閉包引用了外部函數(shù)的局部變量,則外部函數(shù)的局部變量沒有及時(shí)釋放,消耗內(nèi)存。