最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中的閉包使用及作用

 更新時間:2022年08月05日 15:35:12   作者:Python熱愛者  
這篇文章主要介紹了Python中的閉包使用及作用,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

1.什么是閉包

當(dāng)我們在外部函數(shù)中定義了一個內(nèi)部函數(shù),并且內(nèi)部函數(shù)能夠讀取到外部函數(shù)內(nèi)的變量,這種函數(shù)我們就稱為閉包。簡單來說,閉包就是能夠讀取外部函數(shù)內(nèi)的變量的函數(shù)。

閉包的架子大概是這樣:

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)

上面代碼執(zhí)行結(jié)果如下:

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

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

2.閉包的實(shí)例

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

對于該問題,因?yàn)樾枰诤瘮?shù)內(nèi)部對函數(shù)外部的變量進(jìn)行處理,我們可能會考慮使用 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

上面代碼中,我們在函數(shù)中通過全局變量 global 將 sum 聲明為全局變量,最終返回的結(jié)果也符合我們的期望。但因?yàn)槿肿兞刻`活了,不同模塊函數(shù)都能自由訪問到全局變量,所以一般不推薦在函數(shù)內(nèi)部中定義全局變量。

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

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

在上面的閉包函數(shù)中,定義了外層函數(shù)和內(nèi)層嵌套函數(shù),執(zhí)行過程中,調(diào)用外層函數(shù) get_add_sum 返回的就是內(nèi)層嵌套函數(shù) add_num ,因?yàn)镻ython中函數(shù)也是對象,所以可以直接返回 add_num 。

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

我們再來看一個例子:

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

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

上面代碼的執(zhí)行結(jié)果如下:

外部的i值:0
外部的i值:1
外部的i值:2
內(nèi)部的i值:2
內(nèi)部的i值:2
內(nèi)部的i值:2
[12, 12, 12]

可以看到 res 的結(jié)果并不是 [10, 11, 12] ,因?yàn)?i 是外層函數(shù)的變量,并且其值是按 0,1,2 變化,因?yàn)樵摵瘮?shù)中無法保存外層函數(shù)的變量,故對于內(nèi)部函數(shù),其實(shí)際只能訪問到最后外部變量的值 2 ,導(dǎo)致最終結(jié)果為:[12, 12, 12]。

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

def outer(i):
    print("外部的i值:{}".format(i))
    def inner(x):
        print("內(nèi)部的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)

上面代碼的執(zhí)行結(jié)果如下:

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

3.閉包和裝飾器的區(qū)別

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

我們可以打印 閉包 和 裝飾器 的屬性 __closure__ ,如果一個函數(shù)是閉包,那么查看該屬性將會返回一個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__))

執(zhí)行結(jié)果如下:

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

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

到此這篇關(guān)于Python中的閉包使用及作用的文章就介紹到這了,更多相關(guān)Python閉包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python實(shí)現(xiàn)批量文件重命名

    python實(shí)現(xiàn)批量文件重命名

    這篇文章主要介紹了python實(shí)現(xiàn)批量文件重命名,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • python畫微信表情符的實(shí)例代碼

    python畫微信表情符的實(shí)例代碼

    這篇文章主要介紹了python畫微信表情的實(shí)例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • python 爬蟲 批量獲取代理ip的實(shí)例代碼

    python 爬蟲 批量獲取代理ip的實(shí)例代碼

    今天小編就為大家分享一篇python 爬蟲 批量獲取代理ip的實(shí)例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Python語言編寫智力問答小游戲功能

    Python語言編寫智力問答小游戲功能

    這篇文章主要介紹了使用Python代碼語言簡單編寫一個輕松益智的小游戲,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • python環(huán)境的報(bào)錯解決方法

    python環(huán)境的報(bào)錯解決方法

    這篇文章主要為大家介紹了python環(huán)境的報(bào)錯解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 打開并讀取npy文件,查看文件內(nèi)容方式

    打開并讀取npy文件,查看文件內(nèi)容方式

    這篇文章主要介紹了打開并讀取npy文件,查看文件內(nèi)容方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 如何修改新版Python的pip默認(rèn)安裝路徑

    如何修改新版Python的pip默認(rèn)安裝路徑

    pip安裝的第三方庫默認(rèn)存放在C盤中,為了便于管理和不過度占用C盤空間所以想修改默認(rèn)的pip路徑,這篇文章主要介紹了修改新版Python的pip默認(rèn)安裝路徑的過程,需要的朋友可以參考下
    2024-03-03
  • python 如何將帶小數(shù)的浮點(diǎn)型字符串轉(zhuǎn)換為整數(shù)

    python 如何將帶小數(shù)的浮點(diǎn)型字符串轉(zhuǎn)換為整數(shù)

    在python中如何實(shí)現(xiàn)將帶小數(shù)的浮點(diǎn)型字符串轉(zhuǎn)換為整數(shù)呢?今天小編就為大家介紹一下解決方案,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 最新評論

    深水埗区| 黄冈市| 兴宁市| 宝丰县| 鱼台县| 宁南县| 察雅县| 辽宁省| 仙居县| 金门县| 巴彦淖尔市| 巴东县| 青冈县| 澎湖县| 南部县| 金乡县| 宁波市| 彰武县| 商洛市| 潼关县| 抚松县| 类乌齐县| 拜城县| 施秉县| 常山县| 潼关县| 鹤山市| 太谷县| 荆州市| 永清县| 淮滨县| 枣强县| 仪陇县| 格尔木市| 新乡市| 雷山县| 泽普县| 佳木斯市| 醴陵市| 陇川县| 克什克腾旗|