中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中閉包的作用是什么及怎么使用

發布時間:2022-08-08 16:16:44 來源:億速云 閱讀:149 作者:iii 欄目:開發技術

這篇文章主要講解了“Python中閉包的作用是什么及怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python中閉包的作用是什么及怎么使用”吧!

1.什么是閉包

當我們在外部函數中定義了一個內部函數,并且內部函數能夠讀取到外部函數內的變量,這種函數我們就稱為閉包。簡單來說,閉包就是能夠讀取外部函數內的變量的函數。

閉包的架子大概是這樣:

def demo_outer(x):
    def demo_inner(y):
        print("x的值:{}, y的值:{}, x + y 的值:{}".format(x, y, x + y))
    return demo_inner
do = demo_outer(12)
do(34)

上面代碼執行結果如下:

x的值:12, y的值:34, x + y 的值:46

上面的閉包代碼,和我們之前學習的裝飾器類似,我們在外部函數 demo_outer 下定義了一個內部函數 demo_inner ,并且外部函數的返回值就是內部函數,同時在內部函數中,我們引用到了外部函數的變量 x ,而閉包的作用就是可以將外層函數的變量保存在內存中而不被銷毀。

2.閉包的實例

我們先準備一個函數add(),每次調用該函數都只能傳一個數 num ,每次返回的結果都是基于上一次結果的值 sum 進行累加操作。例如,sum的默認值為0,如果我們依次調用 add(10)、add(20)、add(30) 后,期望得到的最終結果是 sum = 60。

對于該問題,因為需要在函數內部對函數外部的變量進行處理,我們可能會考慮使用 global 來處理。

sum = 0
def get_add_sum(num):
    global sum
    sum += num
    return sum
print(get_add_sum(10))  # 輸出:10
print(get_add_sum(20))  # 輸出:30
print(get_add_sum(30))  # 輸出:60
print(sum)  # 輸出:60

上面代碼中,我們在函數中通過全局變量 global 將 sum 聲明為全局變量,最終返回的結果也符合我們的期望。但因為全局變量太靈活了,不同模塊函數都能自由訪問到全局變量,所以一般不推薦在函數內部中定義全局變量。

對于上面的問題,除了使用全局變量外,我們還可以通過 閉包 來實現。

sum = 0
def get_add_sum(sum):
    def add_num(num):
        nonlocal sum
        sum += num
        return sum
    return add_num

add = get_add_sum(sum)
print(add(10))  # 輸出:10
print(add(20))  # 輸出:30
print(add(30))  # 輸出:60

print(sum)  # 輸出:0

在上面的閉包函數中,定義了外層函數和內層嵌套函數,執行過程中,調用外層函數 get_add_sum 返回的就是內層嵌套函數 add_num ,因為Python中函數也是對象,所以可以直接返回 add_num 。

而在內層嵌套函數中則實現了我們想要的累加操作,在這里我們需使用關鍵字 nonlocal 來聲明外層函數中的變量,否則無法對外層函數中的變量進行修改,其作用域只在閉包函數里面,所以當我們在最后打印 sum 最終結果,輸出的仍然是其初始值 0 。

我們再來看一個例子:

def outer():
    res = []
    for i in range(3):
        print("外部的i值:{}".format(i))
        def inner(x):
            print("內部的i值:{}".format(i))
            return i + x
        res.append(inner)
    return res

temp = outer()
res = [i(10) for i in temp]
print(res)

上面代碼的執行結果如下:

外部的i值:0
外部的i值:1
外部的i值:2
內部的i值:2
內部的i值:2
內部的i值:2
[12, 12, 12]

可以看到 res 的結果并不是 [10, 11, 12] ,因為 i 是外層函數的變量,并且其值是按 0,1,2 變化,因為該函數中無法保存外層函數的變量,故對于內部函數,其實際只能訪問到最后外部變量的值 2 ,導致最終結果為:[12, 12, 12]。

在這里,我們可以使用閉包來保存函數的外部變量,修改代碼如下:

def outer(i):
    print("外部的i值:{}".format(i))
    def inner(x):
        print("內部的i值:{}".format(i))
        return i + x
    return inner

def demo():
    res = []
    for i in range(3):
        res.append(outer(i))
    return res

temp = demo()
res = [i(10) for i in temp]
print(res)

上面代碼的執行結果如下:

外部的i值:0
外部的i值:1
外部的i值:2
內部的i值:0
內部的i值:1
內部的i值:2
[10, 11, 12]

3.閉包和裝飾器的區別

在Python中,閉包傳遞的參數是變量,裝飾器傳遞的參數是函數對象,它們只是在傳參內容上有不同。那么裝飾器是不是屬于閉包的一種呢,我們要怎么判斷一個函數是否是閉包呢?

我們可以打印 閉包 和 裝飾器 的屬性 __closure__ ,如果一個函數是閉包,那么查看該屬性將會返回一個cell對象組成的tuple對象。

def demo_outer(x):
    """
    閉包
    """
    def demo_inner(y):
        print("x的值:{}, y的值:{}, x + y 的值:{}".format(x, y, x + y))
    return demo_inner
def demo_decorator(func):
    """
    裝飾器
    """
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@demo_decorator
def method():
    pass

do = demo_outer(5)  # 閉包
print("閉包的屬性:{}".format(do.__closure__))
dd = demo_decorator(method)  # 裝飾器
print("裝飾器的屬性:{}".format(dd.__closure__))

執行結果如下:

閉包的屬性:(<cell at 0x0000023F48C3C8E8: int object at 0x00007FF92017D4A0>,)
裝飾器的屬性:(<cell at 0x0000023F48C3C8B8: function object at 0x0000023F48CB97B8>,)

所以結合上面的結果,我們也可以這樣理解:裝飾器本質上就是一個閉包函數,它只是一個傳遞函數對象的閉包函數。

感謝各位的閱讀,以上就是“Python中閉包的作用是什么及怎么使用”的內容了,經過本文的學習后,相信大家對Python中閉包的作用是什么及怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太白县| 上饶县| 志丹县| 石台县| 密云县| 黔西| 永兴县| 清流县| 涞源县| 西林县| 平湖市| 青神县| 灯塔市| 绥江县| 沧源| 鹤壁市| 措勤县| 偏关县| 新丰县| 香格里拉县| 无棣县| 鹿邑县| 九江市| 象州县| 彝良县| 揭阳市| 万盛区| 宜城市| 莒南县| 萝北县| 博客| 专栏| 丘北县| 靖安县| 霍州市| 札达县| 当阳市| 洛南县| 如皋市| 富源县| 天台县|