首先理解:函數(shù)就是變量
python中定義函數(shù)其實(shí)就是定義一個(gè)類型是 function 的變量,函數(shù)名就是變量名。
一、高階函數(shù)
1、實(shí)參高階函數(shù):參數(shù)是函數(shù)的函數(shù)就是實(shí)參高階函數(shù)
# a.變量可以作為函數(shù)的參數(shù)(實(shí)參)
def func2(x):
print(x)
m = 12.5
func2(10)
func2(m)
# b.實(shí)參高階函數(shù)
def func3(x):
print(x(1, 2))
func3(lambda m, n: m+n)
2、系統(tǒng)提供的常見的實(shí)參高階函數(shù)
- max、min、sorted都是實(shí)參高階函數(shù),有一個(gè)參數(shù)key需要傳一個(gè)函數(shù);被傳入的函數(shù)需要一個(gè)參數(shù)和一個(gè)返回值,這個(gè)參數(shù)指向的是序列中的元素,返回值是比較對象。
#示例一:求列表中數(shù)字各位數(shù)和最大的元素
list2 = [19, 90, 78, 67]
def func3(item):
# 個(gè)位數(shù)最大的元素
# return item%10
# 各位數(shù)的和的最大值
sum1 = 0
for x in str(item):
sum1 += int(x)
return sum1
print(max(list2, key=func3)) # 78
# 示例二:求列表中個(gè)位數(shù)最大的元素
print(max(list2, key=lambda item: item % 10))
# 實(shí)例三:用max函數(shù)獲取學(xué)生列表中成績最高的學(xué)生
students = [
{'name': '張三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
# 獲取成績最高的學(xué)生
best_stu = max(students, key=lambda item: item['score'])
print(best_stu)
# 獲取年齡最小的學(xué)生
min_stu = min(students, key=lambda item: item['age'])
print(min_stu)
# 將學(xué)生列表按照年齡值從小到大排序
new_students = sorted(students, key=lambda item: item['age'])
print(new_students)
3、map函數(shù)
- map(函數(shù),序列) - 將序列中所有的元素按照函數(shù)指定的規(guī)則進(jìn)行轉(zhuǎn)換, 返回的是map的對象(map就是容器型數(shù)據(jù)類型中的一種)。
- 函數(shù)需要一個(gè)參數(shù)和一個(gè)返回值,參數(shù)指向的是序列中的元素,返回值就是用來替換原來元素的新元素
list3 = [10, 20, 30, 40]
# 示例1:將列表list3中所有的元素都加1 -> [11, 21, 31, 41]
new_list3 = map(lambda item: item+1, list3)
print(new_list3, list(new_list3))
# 示例2:將列表list3中的所有的元素都轉(zhuǎn)換成對應(yīng)的字符串: ['10', '20', '30', '40']
new_list3 = map(str, list3)
print(list(new_list3)) # ['10', '20', '30', '40']
4、reduce函數(shù)
- reduce(函數(shù),序列) - 對序列中的元素按照函數(shù)提供的功能進(jìn)行累積的操作
- 函數(shù)需要兩個(gè)參數(shù),第一個(gè)參數(shù)是初始化或者上次運(yùn)算的結(jié)果,y指向每一個(gè)元素
- reduce(函數(shù),序列, 初始值)
from functools import reduce
list3 = [10, 20, 30, 40]
# 示例一: 求所有元素的和
result = reduce(lambda x, y: x+y, list3)
print(result)
# 示例二:求所有元素的乘積
result = reduce(lambda x, y: x*y, list3)
print(result)
# 示例三:求整個(gè)班級所有學(xué)生的總成績
students = [
{'name': '張三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
result = reduce(lambda x, y: x + y['score'], students, 0)
print(result)
5、返回值高階函數(shù):返回值是函數(shù)的函數(shù)
# func1是返回值高階函數(shù)
def func1():
def func2(x, y):
return x + y
return func2
print(func1()(100, 200)) # func2(100, 200)
二、裝飾器
1、裝飾器的作用
- 在不修改函數(shù)的情況下給函數(shù)添加新的功能
- 裝飾器的本質(zhì)就是一個(gè)函數(shù)(這個(gè)函數(shù)是一個(gè)實(shí)參高階函數(shù)也是返回值高階函數(shù))
2、裝飾器的寫法
無參裝飾器的寫法:
def 函數(shù)名1(函數(shù)名2):
def 函數(shù)名3(*agrs, **kwargs):
新功能代碼
返回值 = 函數(shù)名2(*agrs, **kwargs)
return 返回值
return 函數(shù)名3
說明:
函數(shù)名1 - 裝飾器名字,命名的時(shí)候和這個(gè)裝飾器要添加的功能進(jìn)行關(guān)聯(lián)
函數(shù)名2 - 隨便命名,指向被添加功能的函數(shù); 可以命名成 fn
函數(shù)名3 - 隨便命名,在原函數(shù)上添加完新的功能以后產(chǎn)生的新的函數(shù)
新功能代碼 - 實(shí)現(xiàn)新加的功能的代碼
補(bǔ)充:定義函數(shù)的時(shí)候*args和**kwargs同時(shí)存在的意義 - 不定參數(shù)的函數(shù)在調(diào)用的時(shí)候既可以使用位置參數(shù)也可以使用關(guān)鍵字參數(shù)
- 舉個(gè)例子:寫一個(gè)裝飾器將返回值是字符串的函數(shù),返回值中所有的小寫字母變成大寫字母。
def yt_upper(fn):
# fn = str_func
def new_fn(*args, **kwargs):
result = fn(*args, **kwargs)
if type(result) == str:
return result.upper()
else:
return result
return new_fn
@yt_upper
def str_func():
return 'abc'
print(str_func()) #ABC