1.高階函數
- 接收函數作爲參數
# 高階函數——接收函數作爲參數,或接收函數作爲返回值
# 定義一個函數將列表中所有的偶數保存到一個新的列表中
lst1 = [1, 2, 3, 4, 5, 6, 7, 8]
# 高階函數
# 函數作爲參數——此時就是將一段代碼傳遞到函數中啦
# 檢查奇偶、是否大於3
def fn1(i):
if i % 2 == 0:
return True
def fn2(i):
if i % 2 != 0:
return True
def fn3(i):
if i > 3:
return True
def fn(func, lst):
new_list = []
# 遍歷
for i in lst:
# 判斷 調用函數——注意這裏時函數調用不是函數對象
if func(i):
new_list.append(i)
# 返回
return new_list
s = fn(fn3, lst1)
print(s)
- 將函數作爲返回值返回
1.1 匿名函數
'''
filter(func, lst)可以從序列裏過濾出符合條件的元素,保存到一個新的序列中
參數一func 這是一個函數對象,根據這個函數來過濾
參數二lst 這是一個序列,是需要進行過濾的對象
返回值 這是過濾後產生的新序列
'''
lst = [1, 2, 3, 6, 5, 9, 12]
def fn1(i):
if i % 3 == 0:
return True
return False
# def fn(func, lst):
# new_lst = []
# for i in lst:
# if fn1(i):
# new_lst.append(i)
# return new_lst
# print(fn(fn1, lst))
s = list(filter(fn1, lst))
print(s)
# 匿名函數 lambda 函數表達式
# lambda函數表達式專門用來創建一些簡單的函數,是函數的另一種表達方式
# 語法:lambda 參數列表:返回值
# 常規函數
def fm(a, b):
return a + b
# 匿名函數
fm1 = lambda a,b: a + b
print(s(1, 2))
2.閉包
- 將函數作爲返回值返回的高階函數我們又稱之爲閉包
# 高階函數
# 以函數作爲返回值,又稱爲閉包
# 通過閉包可以創建一些只有當前函數可以訪問的變量 a
# 可以將一些私有的變量藏到閉包中
def fn():
a = 123
def fn1():
print('我是fn1...', a)
return fn1
s = fn()
print(s) # <function fn.<locals>.fn1 at 0x0000000002880620>
print(s()) # 我是fn1... 123
# None
s() # 我是fn1... 123
print(a) # NameError: name 'a' is not defined
-
閉包的好處
。通過閉包可以創建一些只有當前函數可以訪問的變量
。可以將一些私有數據藏到閉包中 -
形成閉包的條件
。函數嵌套
。將內部函數作爲返回值返回
。內部函數必須要使用到外部函數的變量
# 求列表中元素的平均值
# nums = [4, 4, 6, 3, 7, 8, 9]
# print(sum(nums) / len(nums))
# 定義一個函數求平均值
# 我不成熟的寫法
# nums = [4, 4, 6, 3, 7, 8, 9]
# def average(nums):
#
# return sum(nums) / len(nums)
#
# print(average(nums))
# 老師的寫法
# nums = [] 寫在全局時容易被修改
# 閉包三條件,缺一不可:
# 閉包——函數嵌套
# 閉包——內部函數作爲返回值
# 閉包——內部函數用到外部函數的變量
def make_average():
nums = []
def average(n):
nums.append(n)
return sum(nums) / len(nums)
# print(average(10)) # 10.0
# print(average(5)) # 7.5
return average
fn = make_average()
print(fn(10)) # 10.0
print(fn(5)) # 7.5
3.裝飾器的引入
- 我們可以直接修改函數中的代碼來滿足要求,但是往往伴隨以下問題:
。如果修改的函數比較多,就比較麻煩
。不方便後期維護
。違反開閉原則ocp(程序設計要求開發對程序的擴展,關閉對程序的修改)
4.裝飾器的使用
- 通過裝飾器可以在不修改原來函數的情況下,對函數進行修改
- 在開發中,我們都是通過裝飾器來擴展函數的功能的
# 裝飾器 —— 類似於start_end(old)這種不用對原函數修改就能對其功能進行擴展的函數
def start_end(old):
# 創建一個新的函數
def new_function(*args,**kwargs):
print('開始執行..')
# fn()
r=old(*args,**kwargs)
print('執行結束..')
return r
return new_function
# 裝飾器的寫法
@start_end
def speak():
print('同學們好好複習啊')
speak()
@start_end
def fn():
print('我是fn函數')
fn()
@start_end
def add(a,b):
r = a+b
return r
r=add(123,123)
print(r)