三大神器其一 裝飾器(高階函數(shù)與裝飾器)

首先理解:函數(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容