在函數內部再定義一個函數,并且這個函數用到了外邊函數的變量,那么將這個函數以及用到的一些變量稱之為閉包。在了解閉包之前,先了解一下函數的引用。
def test():
print('...test...')
test()
t1 = test
t1()
print(id(test))
print(id(t1))
print('*'*15)
結果如下:
函數的引用.jpg
那閉包是如何在函數內引用函數的?看如下代碼:
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))
結果如下:
閉包.jpg
接下來看一個閉包的實際例子,定義一個函數曲線,給定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))
結果如下:
閉包實例.jpg
這個例子中,函數fun1與變量k,b構成閉包。在創建閉包的時候,我們通過fun1的參數k,b說明了這兩個變量的取值,這樣,我們就確定了函數的最終形式(y=kx+b)。我們只需要變換參數a,b,就可以獲得不同的直線表達函數。由此,我們可以看到,閉包也具有提高代碼可復用性的作用。
如果沒有閉包,我們需要每次創建直線函數的時候同時說明k,b,x。這樣,我們就需要更多的參數傳遞,也減少了代碼的可移植性。
閉包似優化了變量,原來需要類對象完成的工作,閉包也可以完成。
但由于閉包引用了外部函數的局部變量,則外部函數的局部變量沒有及時釋放,消耗內存。