1. 匿名函數(shù)
- 沒有函數(shù)名的函數(shù)就是匿名函數(shù)
- 語法: 變量名 = lambda 形參列表 : 返回值
-
說明:
根據(jù)實(shí)際情況,前面的 “變量名 = ” 可以不要(并非省略)
lambda:關(guān)鍵字,固定寫法
形參列表:不可以通過 “冒號(hào)+類型名” 的方式來說明參數(shù)類型(因?yàn)? + 和后面的冒號(hào)沖突),只能用默認(rèn)值來設(shè)定參數(shù)類型,其他和普通函數(shù) 的形參列表一樣
“ : ”:固定寫法
-
返回值:相當(dāng)于普通函數(shù)中 return 后面的語句,只能有一條語句(不能帶有 return 的語句),因此有多行代碼的普通函數(shù),匿名函數(shù)無法實(shí)現(xiàn)
例: def func(a,b): return a + b print(func(1,2)) # 運(yùn)行結(jié)果: 3 用 lambda 函數(shù)表達(dá)式表示如下: 法一: x = (lambda a,b : a + b) print(x(1,2) # 運(yùn)行結(jié)果: 3 法二: print((lambda a,b : a + b)(1,2)) # 運(yùn)行結(jié)果: 3
2. 高階函數(shù)
可以將其他函數(shù)作為參數(shù),或者將函數(shù)作為返回值返回的函數(shù)就是高階函數(shù)
特點(diǎn)一:函數(shù)接收的參數(shù)是一個(gè)函數(shù)名
-
特點(diǎn)二:返回值中包含函數(shù)
特點(diǎn)一 實(shí)例: # 需求一:將一個(gè)指定列表中的偶數(shù),保存到一個(gè)新的列表中返回 # 需求二:將一個(gè)指定列表中的大于5的數(shù),保存到一個(gè)新的列表中返回 lst = [1,2,3,4,5,6,7,8,9,10] def fn1(a): # 定義一個(gè)函數(shù)用來檢測任意數(shù)的偶數(shù) if a % 2 == 0: return True return False def fn2(b): # 定義一個(gè)函數(shù)用來檢測大于5的數(shù) if b > 5: return True return False def fn(func, lst): # 參數(shù) lst 為要進(jìn)行篩選的列表 new_lst = [] # 創(chuàng)建一個(gè)新的列表 for i in lst: # 對(duì)要篩選的列表進(jìn)行遍歷 if func(i): # 根據(jù)需求進(jìn)行篩選 new_lst.append(i) # 將滿足需求的數(shù)添加到新的列表中 return new_lst # 返回新的列表 print(fn(fn1, lst)) # 運(yùn)行結(jié)果: [2, 4, 6, 8, 10] print(fn(fn2, lst)) # 運(yùn)行結(jié)果: [6, 7, 8, 9, 10]
2.1 map() 函數(shù)
接收兩個(gè)參數(shù),一個(gè)是函數(shù),另一個(gè)是 iterable
-
將傳入的函數(shù)依次作用到每個(gè)元素,并把結(jié)果作為新的 iterable 返回
def f(x): return x*x m = map(f,[1,2,3,4]) # iterable 是惰性序列,因此通過 list() 函數(shù)讓它把整個(gè)序列都計(jì)算出來并返回一個(gè)列表 # m = map(lambda x : x*x, [1,2,3,4]) print(list(m)) # 運(yùn)行結(jié)果: [1, 4, 9, 16] print(tuple(m)) # 運(yùn)行結(jié)果: (1, 4, 9, 16) print(set(m)) # 運(yùn)行結(jié)果: {16, 1, 4, 9} # 不建議用set()
2.2 filter() 函數(shù)
接收一個(gè)函數(shù)和一個(gè)序列(可迭代)
-
將傳入的函數(shù)依次作用于每個(gè)元素,然后根據(jù)返回值是 True 和 False 決定保留還是丟棄該元素
def fn(n): return n % 2 == 1 f = filter(fn,[1,2,3,4,5,6,7,8,9,10]) # f = filter(lambda n : n % 2 == 1, [1,2,3,4,5,6,7,8,9,10]) print(list(f)) # 運(yùn)行結(jié)果: [1, 3, 5, 7, 9] print(tuple(f)) # 運(yùn)行結(jié)果: (1, 3, 5, 7, 9) print(set(f)) # 運(yùn)行結(jié)果: {1, 3, 5, 7, 9} # 不建議用set()
3. 閉包
將函數(shù)作為返回值也是?階函數(shù)我們也稱為閉包
閉包的好處:
通過閉包可以創(chuàng)建?些只有當(dāng)前函數(shù)能訪問的變量
可以將?些私有數(shù)據(jù)藏到閉包中-
?成閉包的條件:
函數(shù)嵌套
將內(nèi)部函數(shù)作為返回值返回
內(nèi)部函數(shù)必須要使?到外部函數(shù)的變量實(shí)例: def fn1(): a = 100 def fn2(): print("我是fn2函數(shù)") return a return fn2 print(fn1()()) # 運(yùn)行結(jié)果: 我是fn2函數(shù) 100
4. 裝飾器的引入
- 我們可以直接通過修改函數(shù)中的代碼來完成需求,但是會(huì)產(chǎn)?以下?些問題
- 如果修改的函數(shù)多,修改起來會(huì)?較麻煩
- 不方便后期的維護(hù)
- 這樣做會(huì)違反開閉原則(ocp)
程序的設(shè)計(jì)思想:要求開發(fā)對(duì)程序的擴(kuò)展,要關(guān)閉對(duì)程序的修改
5. 裝飾器的使用
通過裝飾器,可以在不修改原來函數(shù)的情況下來對(duì)函數(shù)進(jìn)?擴(kuò)展
-
在開發(fā)中,我們都是通過裝飾器來擴(kuò)展函數(shù)的功能的
實(shí)例: def fn1(): print("我是fn1函數(shù)") def fn2(a,b): return a + b def start_end(old): # 參數(shù) old 為要擴(kuò)展的函數(shù)對(duì)象 def new_function(*args,**kwargs): # 創(chuàng)建一個(gè)新的函數(shù) print('函數(shù)開始執(zhí)行.....') r = old(*args,**kwargs) print('函數(shù)執(zhí)行結(jié)束.....') return r return new_function # 返回函數(shù) print(start_end(fn1)()) # 運(yùn)行結(jié)果如下: 函數(shù)開始執(zhí)行...... 我是fn1函數(shù) 函數(shù)執(zhí)行結(jié)束...... None print(start_end(fn2)(123,456)) # 運(yùn)行結(jié)果如下: 函數(shù)開始執(zhí)行...... 函數(shù)執(zhí)行結(jié)束...... 579 @start_end def speak(): print('天卓金榜題名') @start_end def listen(): print('助你榜上有名') speak() listen() # 運(yùn)行結(jié)果如下: 函數(shù)開始執(zhí)行..... 天卓金榜題名 函數(shù)執(zhí)行結(jié)束..... 函數(shù)開始執(zhí)行..... 助你榜上有名 函數(shù)執(zhí)行結(jié)束.....