函數不只能夠做爲函數參數,還能夠做爲函數返回結果閉包
def pro1(c,f): def pro2(): return f(c) return pro2 #調用pro1函數時,返回的是pro2函數對象 >>>a = pro1(-3,abs) #須要對a調用才能獲得結果 >>>a() 3
若是在一個內部函數裏對外部做用域(但不是全局做用域)的變量進行引用,內部函數稱爲閉包(closure)app
import math def fun1(n): def fun2(x): return pow(x,n) return fun2 pow2 = fun1(2) print(pow2(9))
#函數fun2對fun1的參數n進行了引用,將帶參數的fun1給一個新的函數pow2函數
當fun1的生命週期結束時,已經引用的變量n存在在fun2中,依然能夠調用code
#用閉包實現一個點與點之間的距離計算 def point(x, y): def get_distance(u, v): return sqrt((x - u) ** 2 + (y - v) ** 2) return get_distance >>> pt = point(7, 2) >>> pt(10, 6) 5.0
再看一個廖老師的例子對象
def count(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fs f1, f2, f3 = count()
若是你認爲f1,f2,f3三個不一樣的函數分別返回1,4,9。那就錯了生命週期
由於返回函數使用了循環變量i,可是並無馬上執行 等到函數所有返回後,i已是3,獲得的結果所有是9作用域
所以,咱們應儘可能避免在閉包中引用循環變量,或者後續會發生變化的變量。get
若是須要引用循環變量,增長一個函數,而且使用該函數的參數綁定循環變量當前的值。import
def count(): fs = [] for i in range(1,4): def g(a): #定義一個g函數,參數爲a,返回函數f的返回值被綁定 f = lambda : a*a return f fs.append(g(i)) return fs f1,f2,f3 =count() print(f1()) print(f2()) print(f3()) 1 4 9
匿名函數匿名函數
所謂匿名就是不須要函數表達式
lambda x : x*x
關鍵字lambda
表示匿名函數,冒號前面的x
表示函數參數。
匿名函數有個限制,就是隻能有一個表達式,不用寫return
,返回值就是該表達式的結果。
#定義一個函數f,參數爲a 返回a的平方 這裏將匿名函數賦值給變量f f = lambda a: a*a >>>f(3) 9