返回函數
阿新 • • 發佈:2017-11-06
closure 調用 args code 0x03 div top func 可選 #我們前面了解了函數可以有返回值,除了返回值,函數中是否可以返回函數呢?
#例如,定義如下函數並執行:
1 # /usr/bin/python3 2 #!-*-conding:UTF-8 -*- 3 #返回函數 4 5 def calc_sum(*args): 6 ax=0 7 for n in args: 8 ax=ax+n 9 return ax#這裏定義了一個可選參數的求和函數,該函數允許傳入多個參數,最後返回求得的和。如果不需要立刻求和,而是在後面的代碼中根據需要在計算,怎麽操作呢?例如,函數定義如下:
1 def sum_late(*args):#可以看到,此處返回了一個我們之前沒有看過的類型的值,是返回了一個函數嗎?是的,此處確實返回了一個函數。對於此處定義的函數,我們返回求和的結果,而是返回了一個求和函數。 #操作執行函數:2 def calc_sum(): 3 ax=0 4 for n in args: 5 ax=ax+n 6 return ax 7 return calc_sum
1 print(‘調用sum_late的結果:‘,sum_late(1,2,3,4)) 2 calc_sum=sum_late(1,2,3,4) 3 print#得到函數的執行結果如下:(‘調用calc_sum的結果:‘,calc_sum())
1 調用sum_late的結果: <function sum_late.<locals>.calc_sum at 0x03141F60> 2 調用calc_sum的結果: 10#由執行結果看到,調用定義的函數時沒有直接返回求和結果,而是返回了一串字符(這個字符其實就是函數)。當執行返回的函數時,才真正計算求和的結果。 #在這個例子中,在函數sum_late中又定義了calc_sum,並且內部函數calc_sum可以引用外部函數sum_late的參數和局部變量。當sum_late返回calc_sum時,相關參數和變量都保存在返回的函數中,稱為閉包(closure)。這種程序結構威力極大。 #有一點需要註意,當調用sum_late函數時,每次調用都會返回一個新的函數,即使傳入相同的參數也是如此,例如:
1#執行結果如下:f1=sum_late(1,2,3) 2 f2=sum_late(1,2,3) 3 print(‘f1==f2的結果為:‘,f1==f2)
1 ==================== RESTART: C:/Users/L/Desktop/返回函數.py ==================== 2 f1==f2的結果為: False#由執行結果看到,返回的函數f1和f2不同。 #我們在此處提到了閉包(closure),什麽是閉包呢? #閉包的定義:如果在一個內部函數裏對外部函數(不是在全局作用域)的變量進行引用,內部函數就被認為是閉包。 #在上面的示例中,返回的函數在定義內部引用了局部變量args,當函數返回了一個函數後,內部的局部變量會被新函數引用。 #例如,我們定義一個函數:
1 # /usr/bin/python3 2 #!-*-conding:UTF-8 -*- 3 #返回函數 4 5 def count(): 6 fs=[] 7 for i in range(1,4): 8 def f(): 9 return i*i 10 fs.append(f) 11 return fs 12 f1,f2,f3=count()#該示例中,每次循環都會創建一個新函數,最後把創建的3個函數都返回了。執行該函數得到的結果是怎樣的呢?調用f1(),f2(),f3()的結果是1,4,9嗎? #我們執行如下函數:
1 # /usr/bin/python3 2 #!-*-conding:UTF-8 -*- 3 #返回函數 4 5 def count(): 6 fs=[] 7 for i in range(1,4): 8 def f(): 9 return i*i 10 fs.append(f) 11 return fs 12 f1,f2,f3=count() 13 print(‘f1的結果是:‘,f1()) 14 print(‘f2的結果是:‘,f2()) 15 print(‘f3的結果是:‘,f3())#執行結果如下:
1 f1的結果是: 9 2 f2的結果是: 9 3 f3的結果是: 9#由執行結果看到,3個函數返回的結果都是9,為什麽全是9? #原因在於返回的函數引用了變量i,但它並非立刻執行。等到3個函數都返回時,他們所引用的變量i已經變成了3,因此最終結果為9. #返回閉包時,返回函數不要引用任何循環變量或後續會發送變化的變量,否則很容易出現很多意想不到的問題。 #如果一定要引用循環變量怎麽辦? #我們定義如下函數並執行:
1 # /usr/bin/python3 2 #!-*-conding:UTF-8 -*- 3 #返回函數 4 5 def count(): 6 def f(j): 7 def g(): 8 return j*j 9 return g 10 fs=[] 11 for i in range(1,4): 12 fs.append(f(i)) #f(i)立刻被執行,因此i的當前值被傳入f() 13 return fs 14 15 f1,f2,f3=count() 16 print(‘f1的結果是:‘,f1()) 17 print(‘f2的結果是:‘,f2()) 18 print(‘f3的結果是:‘,f3())#函數執行結果如下:
1 ==================== RESTART: C:\Users\L\Desktop\返回函數.py ==================== 2 f1的結果是: 1 3 f2的結果是: 4 4 f3的結果是: 9#由執行結果看到,這次輸出結果和我們預期的一致。
返回函數