1. 程式人生 > >返回函數

返回函數

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
#由執行結果看到,這次輸出結果和我們預期的一致。

返回函數