在學習返回函數的時候,函數只是在調用的時候才會運行一直不理解,隔天后在來看的時候明白了一些,記錄一下。
看代碼
>>> def fun1(n): ... def fun2(x): ... return pow(x,n) ... return fun2 ... >>> pow2=fun1(2) >>> pow2 <function fun1.<locals>.fun2 at 0x7f8bdfe2e378> >>> pow2(9) 81
看這個函數的定義是將fun1()下定義的函數fun2()返回fun2()地址,當將fun1(2)的返回的fun2地址賦給pow2后當運行pow2(9)的時候才運行了fun1()內定義的函數即fun2(),即fun1(9,2)。
還有就是返回函數中的在一個內部函數里對外部作用域(但不是全局作用域)的變量進行引用,內部函數稱為閉包(closure)。其中用到了循環
def count(): fs=[] for i in range(1,4): def f(): return i*i #把函數f地址追加至列表fs fs.append(f) #返回為一個包含3個函數f地址的列表 return fs print('count函數返回一個列表,列表分別為函數f地址',count()) f1,f2,f3 = count() print(f1,'f1執行結果是',f1()) print(f2,'f2執行結果是',f2()) print(f3,'f3執行結果是',f3())
count函數返回一個列表,列表分別為函數f地址 [<function count.<locals>.f at 0x7fc5d30cac80>, <function count.<locals>.f at 0x7fc5d30cad08>, <function count.<locals>.f at 0x7fc5d30cad90>]
<function count.<locals>.f at 0x7fc5d30cac80> f1執行結果是 9
<function count.<locals>.f at 0x7fc5d30cad08> f2執行結果是 9
<function count.<locals>.f at 0x7fc5d30cad90> f3執行結果是 9
結果全是9,而不是所希望的1,4,9
在這個函數中i是count函數的局部變量
當i= 1時,i指向了1,結果返回了函數的地址放在了fs的第一個位置。
當i = 2時,又將i 指向了2,函數地址返回到了fs的第二個位置上。
當i = 3 時,i 指向了3,然后返回了函數地址在fs的第三個位置。
所以當調用函數顯示的時候,i 已經是3,所以得到的結果是一樣的。
def count(): fs=[] for i in range(1,4): def f(j): def g(): return j*j return g fs.append(f(i)) #返回為一個包含3個函數f地址的列表 return fs print('count函數返回一個列表,列表分別為函數f地址',count()) f1,f2,f3 = count() print(f1,'f1執行結果是',f1()) print(f2,'f2執行結果是',f2()) print(f3,'f3執行結果是',f3())
count函數返回一個列表,列表分別為函數f地址 [<function count.<locals>.f.<locals>.g at 0x7ff488311d08>, <function count.<locals>.f.<locals>.g at 0x7ff488311c80>, <function count.<locals>.f.<locals>.g at 0x7ff488311d90>]
<function count.<locals>.f.<locals>.g at 0x7ff488311c80> f1執行結果是 1
<function count.<locals>.f.<locals>.g at 0x7ff488311d08> f2執行結果是 4
<function count.<locals>.f.<locals>.g at 0x7ff488311d90> f3執行結果是 9
這樣修改后就得到了希望的結果。
代碼中f(j)將循環中i的值傳給了j,當i處於循環中時返回的函數並不是指向i,而是將它的數值傳給了j並指向j。