一.高階函數(shù)
-->分類:
? ????? 1.將函數(shù)作為參數(shù)? ? 2.將函數(shù)作為返回值
-->好處:
? ? ????1.當使用函數(shù)作為參數(shù)的時候,實際是將函數(shù)代碼傳入到目標函數(shù),交互性好
-->不同的函數(shù)實現(xiàn)不同的功能,滿足不同用戶需求,簡單示例
求偶數(shù)
def fn1(n):
? ? if n % 2 == 0:
? ? ? ? return True
大于5
def fn2(n):
? ? if n > 5:
? ? ? ? return True
3的倍數(shù)
def fn3(n):
? ? if n % 3 == 0:
? ? ? ? return True
lst = [1,2,3,4,5,6,7,8,9]
def fn(fun,l):????#傳入函數(shù)參數(shù)
? ? lst1 = []
? ? for i in l:
? ? ? ? if fun(i) : ????#調(diào)用函數(shù)
? ? ? ? ? ? lst1.append(i)
? ? return lst1
print(fn(fn3,lst))? #[3, 6, 9]
二.匿名函數(shù)
格式:filter(function,interable)
function: 函數(shù)名
interable: 可迭代對象
返回值:對象
lst = [1,2,3,4,5,6,7,8,9,10]
def fn1(n):
? ? ?if n > 5:
? ? ? ? ?return True
print(filter(fn1,lst))
print(list(filter(fn1,lst)))
# <filter object at 0x0000024456291CF8>
# [6, 7, 8, 9, 10]
-->由于創(chuàng)建的函數(shù)內(nèi)容(實現(xiàn)功能簡單),引入匿名函數(shù)
????????1.占用空間小,
????????2.只會調(diào)用一次,就會在內(nèi)存中消失了
-->匿名函數(shù)lambda
????????格式: lambda 參數(shù)表達式;返回值
r =lambda a,b : a + b
print(r)????# at 0x000002037A2EC268>
print(r(100,200))????#300
三.閉包
-->高階函數(shù)第二種形式:將函數(shù)作為返回值
-->通過閉包創(chuàng)建一個只有當前函數(shù)才能返回的變量,我可以將一些私有數(shù)據(jù)放到閉包中
形成閉包的條件:
? ? 1.函數(shù)嵌套? ??
????2.內(nèi)部函數(shù)使用了外部函數(shù)的變量(還包括外部函數(shù)的參數(shù))?
????3.外部函數(shù)返回了內(nèi)部函數(shù)
實例如下:
def num_add():
lst = []
????def fn(n):
????lst.append(n)
????return sum(lst) /len(lst)
return fn
r = num_add()
print(r(10))
print(r(20))
lst = [ ]???? 無影響,不改變運行結(jié)果
lst = 7? 無影響, 不改變運行結(jié)果
print(r(30))
# 10.0
# 15.0
# 20.0
四.裝飾器
-->我們可以直接修改函數(shù)代碼完成需求,但是會產(chǎn)生一些問題? ??
????????1.如果修改的函數(shù)較多,修改起來麻煩? ?
?????????2.不方便后期維護? ??
????????3.這種方式會違反OCP原則(擴展代碼,但不允許修改源碼)
-->例子:對f4函數(shù)擴展
def f4():
#? ? print('我是F4')
# def f5():
#? ? print('函數(shù)開始')
#? ? f4()
#? ? print('函數(shù)結(jié)束')
# f5()
# 函數(shù)開始
# 我是F4
# 函數(shù)結(jié)束
-->擴展案例
def add(a,b):
# 求任意兩個數(shù)的和
? ? # print('開始運行')
? ? r = a + b
# print('結(jié)束運行')
? ? return r
# v = add(109,108)
# print(v)
# 開始運行
# 結(jié)束運行
# 217
def new_add(a,b):
print('開始運行')
print('結(jié)束運行')
return add(a,b)
print(new_add(123,543))
# 開始運行
# 結(jié)束運行
# 666
-->裝飾器的使用
def add(a,b):
????r = a + b
return r
def f_start(old):????#傳入函數(shù)參數(shù),對其進行拓展
? ? def new_fun(*a,**b):????#接收多種參數(shù)
? ? ? ? print('開始執(zhí)行')
res = old(*a,**b)
print('結(jié)束執(zhí)行')
return res
return new_fun
r = f_start(add)
value = r(132,543)
print(value)
開始執(zhí)行
結(jié)束執(zhí)行
675?
-->類似于f_start(old)函數(shù)稱之為裝飾器函數(shù)
對傳入的old函數(shù)擴展
-->實際使用
@f_start
def say():
print('hello world')
say()
開始執(zhí)行
hello world
結(jié)束執(zhí)行
五.命名空間
--> locals() 獲取當前作用域的命名空間
a =10? #相當于在命名空間田間key-value ( 'a' = 10)
r =locals()
print(r)
print(r['a'])
# {'__name__': '__main__',
# '__doc__': None,
# '__package__': None,
# '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000211C6E31CF8>,
# '__spec__': None, '__annotations__': {}, '__builtins__': ,
# '__file__': 'C:/untitled/001.小黑/命名空間.py', '__cached__': None, 'r': {...}}
10