Python入門(11.3)

高階函數

滿足兩個條件任意一個都是高階函數
1.接受函數作為參數的函數
2.將函數作為返回值的函數

當我們使用一個函數作為參數時,實際上我們就是將指定的代碼傳遞給了目標函數

l = [1,2,3,4,5,6]
def fn(n):
    if n %2 ==0:
        return True
    return False
def func(func,lst):
    new_lst = []
    for i in lst:
        if fn(i)==True:
            new_lst.append(i)
    return new_lst

print(func(fn,l))
>>>[2, 4, 6]

filter() 可以從序列中過濾出來符合條件的元素,保存到一個新的序列當中
參數:1.函數,根據該函數來過濾序列(可迭代結構)
?????????? 2. 需要過濾的序列(可迭代結構)
返回值:過濾后新的序列

l = [1,2,3,4,5,6]
def fn(n):
    if n %2 ==0:
        return True
    return False
print(filter(fn,l))
print(list(filter(fn,l)))
>>><filter object at 0x0000021D6929E278>
>>>[2, 4, 6]

匿名函數

匿名函數 lambda表達式
lambda函數表達式是用來創(chuàng)建一些簡單的函數 它是函數創(chuàng)建的另外一種方式
語法:lambda 參數列表:返回值
匿名函數最大的好處是只會調用一次,用完之后會從內存消失
匿名函數一般作為參數使用

print(lambda a,b:a+b)
>>><function <lambda> at 0x000001C77671DF28>

print(fn)
>>><function fn at 0x000001DB1E711E18>
# 比較后 可以發(fā)現(xiàn) lambda表達式創(chuàng)建的函數 沒有名字。。

調用匿名函數

print((lambda a,b:a+b)(1,2))
>>>3

func = lambda a,b:a+b
print(func(1,2))
>>>3

再返回到filter那里

#我們用lambda表達式來替代fn函數
#因為fn函數比較簡單 功能單一 且只調用一次 不會再調用 也不想讓fn函數在全局作用域當中
print(list(filter(lambda i:i%2==0,l)))
>>>[2, 4, 6]

map()函數可以對 可迭代對象 中所有元素做指定的操作,然后將其添加到一個新的對象中返回

l = [1,2,3,4,5,6]
result = map(lambda i:i+1,l)
print(list(result))
>>>[2, 3, 4, 5, 6, 7]

sort()函數可以對列表當中的元素進行排序(列表對象 調用)
sort函數有一個關鍵字 key 需要一個函數作為參數

lst = ['e','cc','dd','bbb','aaaa']
lst.sort(key=len ) #len()函數
print(lst)
>>>['e', 'cc', 'dd', 'bbb', 'aaaa']

lst = [1,2,'3','5',0]
lst.sort(key=int) #int()函數
print(lst)
>>>[0, 1, 2, '3', '5']


sorted(_iterable,key,reverse) 會返回一個新的列表
iterable 可迭代的
reverse 反轉

lst = [1,2,'3','5',0]
l = sorted(lst,key=int)
print('排序前',lst)
print('排序后',l)
>>>排序前 [1, 2, '3', '5', 0]
>>>排序后 [0, 1, 2, '3', '5']


  • 閉包
    將函數作為返回值返回 也是一種高階函數
    通過閉包可以創(chuàng)建一些只有當前函數才能訪問的對象,還可以將一些私有的數據藏到閉包中
def fn():
    #函數內部在定義一個函數
    def fn2():
        print("fn2")
    #在內部函數將fn2作為返回值返回
    return fn2
print(fn())
fn()()
>>><function fn.<locals>.fn2 at 0x000001710661DF28>
>>>fn2

nums = [10,10,20,30,20]
print(sum(nums)/len(nums))
>>>18.0

nums = []
def fn(num):
    nums.append(num)
    print(sum(nums)/len(nums))
fn(10)
fn(10)
fn(20)
fn(20)
>>>10.0
>>>10.0
>>>13.333333333333334
>>>15.0
#但是這種方式 nums為全局變量 不安全  因此引出了閉包


形成閉包的條件:
1.函數嵌套
2.將內部函數作為返回值返回
3.內部函數必須使用到外部函數的變量
什么時候使用到閉包
當你的某些數據不希望被外界訪問和修改的時候 就需要用到閉包
這樣能夠保證數據的安全性

  • 引入裝飾器
def add(a,b):
    print("計算開始")
    r =  a+b
    print("計算結束")
    return r
def mul(a,b):
    print("計算開始")
    r =  a*b
    print("計算結束")
print(add(1,2))
print(mul(1,2))
#我們可以通過修改函數中的代碼來完成,但是會產生一些問題
#1.修改的函數很多 
#2.不方便后期的維護
#3.會違背開閉原則(ocp) 程序設計 要求對程序的擴展,但是要關閉對程序的更新

下面這種寫法就是對程序擴展而不更新 但是不能每調用一個方法 寫一個這種函數

 def add(a,b):
    r =  a+b
    return r
def mul(a,b):
    r =  a*b
    return r

def new_add(a,b):
    print("計算開始")
    r = add(a,b)
    print("計算結束")
    return r
print(new_add(1,2))

于是有了裝飾器

def start_end(func):
    def new_func(*args,**kwargs): #裝包
        print("程序開始")
        res=func(*args,*kwargs) #解包
        print("程序結束")
        return res
    return new_func

def add(a,b):
    return a + b

def pr():
    print("Hello")

print(start_end(add)(1,2))
start_end(pr)()
>>>程序開始
>>>程序結束
>>>3

>>>程序開始
>>>Hello
>>>程序結束

def start_end(func):
    def new_func(*args,**kwargs): #裝包
        print("程序開始")
        res=func(*args,*kwargs) #解包
        print("程序結束")
        return res
    return new_func

@start_end
def add(a,b):
    return a + b
print(add(1,2))

@start_end
def pr():
    print("Hello")
pr()

>>>程序開始
>>>程序結束
>>>3

>>>程序開始
>>>Hello
>>>程序結束

#start_end(func) 類似這樣的函數其實就是一個裝飾器
#在開發(fā)中,都是通過裝飾器來擴展函數的功能
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容