python之高階函數、裝飾器、閉包

函數即變量

定義一個函數就是把函數體給函數名。變量先定義後使用,函數一定要先聲明後調用,只要聲明後調用即可,哪個先定義哪個後定義沒有關係。如圖所示:
在這裏插入圖片描述在這裏插入圖片描述

高階函數

所謂高階函數就是1. 把一個函數名當作實參傳給另一個參數;2.把函數作爲結果值返回。
1. 傳入參數

# 高階函數
import time
def a():
    time.sleep(2)
    print("hello,I am a")
def b(fun):
    start_time = time.time()
    fun()  # 此處不要寫成fun
    stop_time = time.time()
    print("the function time is %s" %(stop_time - start_time))
b(a)      # 像變量一樣傳入函數名即可,不要寫成b(a())

在這裏插入圖片描述
2. 返回函數

# 高階函數
import time
def a():
    start_time = time.time()
    time.sleep(2)
    stop_time = time.time()
    print("the function time is %s" %(stop_time - start_time))
def b(fun):
    return fun  # 返回函數
f = b(a) # 當我們調用b(a)時,返回的並不是結果,而是函數本身
f()      # 調用函數

在這裏插入圖片描述
在這裏插入圖片描述

嵌套函數

嵌套不等於調用,即:

def b():
    def a():def b():
    a()
不一樣

在這裏插入圖片描述
可以把內部嵌套函數看作是局部變量。

裝飾器

裝飾器:本質上是函數,功能是裝飾函數,也就是爲其他函數增加新功能。在代碼運行期間動態增加功能的方式叫做裝飾器。
原則:
1.不能修改被裝飾函數的源代碼。
2.不能修改被裝飾函數的調用方式。
裝飾器 = 高階函數 + 嵌套函數

import time
import functools
def b(func):
    @functools.wraps(func)
    def a():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the function time is %s" %(stop_time - start_time))
    return a
@b  # old = b(old) 
def old():  # 被裝飾函數
    time.sleep(2)
    print("hello,我是原來函數")
old()

在這裏插入圖片描述
滿足了不改動原函數和調用方法的原則。

閉包

其實用的還是高階函數,不是立馬返回結果,而是返回函數本身。
1.

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

在函數lazy_sum中又定義了函數sum,並且,內部函數sum可以引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,這種稱爲“閉包(Closure)”。
我們調用lazy_sum()時,每次調用都會返回一個新的函數,即使傳入相同的參數。返回的函數並沒有立刻執行,而是直到調用了纔會執行。
2.

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs
f1, f2, f3 = count() # 列表裏的三個函數,調用時纔會執行
print(f1())
print(f2())
print(f3())

在這裏插入圖片描述
結果並不是1,4,9,原因就在於返回的函數引用了變量i,但它並非立刻執行,等到3個函數都返回時,它們所引用的變量i已經變成了3,因此最終結果都爲9。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章