首先我們先給出閉包的概念,如果內部函式引用了外部函式作用域裡的變數(非全域性變數),則稱這個內部函式以及用到的變數統稱為閉包。
在python中的閉包需要滿足三個條件:
可能這些東西聽起來非常繞嘴,難以理解,下面我們舉個例子。
def func_out(num): #外層函式
# 在函式內部再定義乙個函式,並且這個函式用到了外邊函式的變數,那麼將這個函式以及用到的一些變數稱之為閉包
def func_in(num_in): #內層函式
print("在內層函式裡, num_in is %d" % num_in)
return num + num_in
# 其實這裡返回的就是閉包的結果
return func_in #這裡返回就是內層函式名字func_in
# 給func_out函式賦值,這個20就是給引數num
pnum = func_out(20)
# 注意 這裡的100其實給引數numb_in
print(pnum(100))
#注 意這裡的200其實給引數numb_in
print(pnum(200))
讓我們看看執行的結果:
在內層函式裡, num_in is 100
120在內層函式裡, num_in is 200
220
在開發中,用到閉包可以提高的**的復用率。下面我們舉乙個初中曾經學習的一次函式y=kx+b的例子
def line_conf(k, b): #外層函式 發生函式巢狀
def line(x): #內層函式
return k*x + b #內層函式引用外層函式的變數 ,格式:y=kx+b
return line #返回內層函式名
line1 = line_conf(2, 1) # k=2 , b=1 -->y=2x+1
print(line1(7)) # y=7*2+1=15
line2 = line_conf(4, 5) # k=4, b=5 -->y=4x+5
print(line2(8)) # y=4*8+5=37
上面的**中,函式line與變數a,b構成閉包。在建立閉包的時候,我們通過line_conf的引數a,b說明了這兩個變數的取值,這樣,我們就確定了函式的最終形式(y = 2x + 1和y = 4x + 5)。
我們只需要變換引數a,b,就可以獲得不同的一次函式的表示式。由此,我們可以看到,閉包也具有提高**可復用性的作用。
如果沒有閉包,我們需要每次建立直線函式的時候同時說明a,b,x。這樣,我們就需要更多的引數傳遞,也減少了**的可移植性。
除此之外,閉包也可以做裝飾器用,比如計算某乙個函式的執行時間
import time
def timer(func):
start_time = time.time() #開始時間
func() #引用外層函式中的變數
stop_time = time.time() #結束時間
print('run time is %f'%(stop_time-start_time))
@timer #定義修飾timer為裝飾器
def fun():
print('函式開始start-----')
time.sleep(3) #函式睡眠3秒鐘
print('函式結束end-------')
if __name__ == '__main__':
fun()
看看執行的結果:
函式開始start-----
函式結束end-------
run time is 3.000939
下面我們總結點閉包的優點:
閉包的缺點:
python中的閉包
python 閉包 python 閉包
閉包 因為python中函式也可以當作物件,所以如果出現當我們返回乙個函式,而該函式含有外部變數的時候就形成了閉包。閉包的特點 是個巢狀函式 可以獲得非區域性的變數 將函式當作物件返回 看乙個例子會更易理解 def make printer msg msg hi there def printer ...
python怎麼閉包 python的閉包
一 思考乙個問題 我們要給定乙個x,要求一條直線上x對應的y的值。公式是y kx b。我們需要用k,b來確定這條直線,則我們實現的函式應該有3個引數 defline k,b,x print k x b line 1,3,4 line 1,3,5 line 1,3,6 可以看到,我們每次修改x都要重新...
python 閉包 Python中的閉包
一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...