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

Python編程中閉包的變量作用域問題解析

 更新時(shí)間:2021年10月21日 14:59:35   作者:曉鵬-King  
這篇文章主要介紹了Python編程中閉包的變量作用域問題解析,在學(xué)習(xí)Python的返回函數(shù)的時(shí)候,我發(fā)現(xiàn)里面涉及了幾個(gè)問題,在這里為大家分享講解下

閉包

​ 在我們使用返回函數(shù)的時(shí)候,由于我們?cè)谝粋€(gè)函數(shù)中需要返回另一個(gè)函數(shù),因此,我們?cè)谶@個(gè)函數(shù)中就需要重新定義一個(gè)函數(shù)。而這樣,就造成了我們的函數(shù)嵌套問題。外面的函數(shù)相對(duì)于里面的函數(shù)而言是外函數(shù)(outer function),而里面的我們叫他內(nèi)函數(shù)(inner function)。

def outerFunction(): #外函數(shù)
    def innerFunction(): #內(nèi)函數(shù)
        x = 1
        return x
    return innerFunction #返回值是一個(gè)函數(shù)
a = outerFunction()
print(a)

這里我們打印 a 的值得時(shí)候,實(shí)際上打印的是我們的返回函數(shù)的地址 :

<function outerFunction.<locals>.innerFunction at 0x0000019C278C0E50>

​ 一般情況下,我們?cè)谑褂煤瘮?shù)作為返回值得時(shí)候,我們會(huì)在內(nèi)函數(shù)中使用我們外函數(shù)中的變量,這種情況就會(huì)產(chǎn)生一個(gè)有意思的事情了。內(nèi)函數(shù)會(huì)被返回給外部的其他調(diào)用者,而我們的變量是在我們的外函數(shù)中定義的。此時(shí),我們的變量的作用域會(huì)發(fā)生怎樣的變化呢?

測(cè)試:

def outerFunction(x): #外函數(shù)
    y = 10
    def innerFunction(): #內(nèi)函數(shù)
        return x + y
    return innerFunction #返回值是一個(gè)函數(shù)
a = outerFunction(10)
print(a())

​打印:

20

​ 這里可以看到,我們的在給 a 賦值的時(shí)候,同時(shí)給外函數(shù)傳進(jìn)去了一個(gè)值10,然后,我們直接把 a() 打印出來,此時(shí),我們的 a 返回了 20,說明我們的變量和參數(shù)在進(jìn)入內(nèi)函數(shù)后,我們的內(nèi)函數(shù)會(huì)保留這個(gè)變量的值。

​ 這里,我們把這種現(xiàn)象叫做“閉包(Closure)”,我試著多次返回這個(gè)內(nèi)函數(shù),看看他們的地址是否一致:

def outerFunction(x): #外函數(shù)
    y = 10
    def innerFunction(): #內(nèi)函數(shù)
        return x + y
    return innerFunction #返回值是一個(gè)函數(shù)
a = outerFunction(10)
b = outerFunction(20)
c = outerFunction(30)
print(a())
print(b())
print(c())
print(a)
print(b)
print(c)

​ 打?。?/p>

20
30
40
<function outerFunction.<locals>.innerFunction at 0x0000020C480C0DC0>
<function outerFunction.<locals>.innerFunction at 0x0000020C480C0D30>
<function outerFunction.<locals>.innerFunction at 0x0000020C480CD280>

​ 這里我們可以看到每個(gè) innerFunction 的地址都不同,當(dāng)我們多次調(diào)用返回函數(shù)的時(shí)候,每調(diào)用一次,我們的返回函數(shù)就會(huì)新創(chuàng)建一個(gè)函數(shù)給我們的變量。

​ 那么,如果我們?cè)谕夂瘮?shù)里面多次調(diào)用我們的內(nèi)函數(shù),我們的外函數(shù)的變量的作用域是什么樣的呢?

​ 我們測(cè)試一下:

def outerFunction(x): #外函數(shù)
    L=[] #定義一個(gè)List 
    y = 10
    for i in range(1, 4):
        def innerFunction(): #內(nèi)函數(shù)
            return (x + y) * i #使用我們外函數(shù)得變量
        print(innerFunction()) #打印內(nèi)函數(shù)返回得值
        #print(innerFunction)
        L.append(innerFunction) #把內(nèi)函數(shù)添加到我們得List中
    return L #返回這個(gè)List
a = outerFunction(10)
print(a[0])
print(a[1])
print(a[2])
print(a[0]())
print(a[1]())
print(a[2]())

​ 看打?。?/p>

20
40
60
<function outerFunction.<locals>.innerFunction at 0x00000274AD6B0E50>
<function outerFunction.<locals>.innerFunction at 0x00000274AD6BD040>
<function outerFunction.<locals>.innerFunction at 0x00000274AD6BD3A0>
60
60
60

​ 這里我們可以看到一個(gè)有意思得現(xiàn)象:

​ 當(dāng)我們?cè)谖覀兊暮瘮?shù)內(nèi)多次調(diào)用我們的內(nèi)函數(shù),并把它的返回值打印出來的時(shí)候,我們可以看到這個(gè)值是正常的(依次遞增)。而如果我們把這個(gè)內(nèi)函數(shù)傳遞到我們的 List 中,在函數(shù)外部調(diào)用它的時(shí)候,我們的函數(shù)的返回值全部變成了 60 也就是他們的只得到了我們外函數(shù)中變量的最終的值。這個(gè)就是我們的閉包特有的現(xiàn)象。

閉包中的變量

​ 一般情況下,當(dāng)一個(gè)函數(shù)結(jié)束的時(shí)候,在內(nèi)存中,我們這個(gè)函數(shù)內(nèi)部的局部變量會(huì)連同這個(gè)函數(shù)一起被釋放掉。

​ 但是,當(dāng)我們這個(gè)函數(shù)包含閉包的時(shí)候,也就是說,當(dāng)這個(gè)函數(shù)的返回值是一個(gè)函數(shù)的引用的時(shí)候。此時(shí),當(dāng)這個(gè)函數(shù)結(jié)束時(shí),由于它內(nèi)部的局部變量需要被釋放掉,因此,它會(huì)把這個(gè)變量的值給傳遞給它所要返回的這個(gè)函數(shù)的內(nèi)部。正是因?yàn)檫@樣,當(dāng)我們?cè)谕獠空{(diào)用我們的返回函數(shù)的時(shí)候,我們會(huì)看到它使用的變量全都是這個(gè)變量在函數(shù)內(nèi)的最終的值,因?yàn)檫@個(gè)變量是這個(gè)外函數(shù)在結(jié)束的時(shí)候才傳遞給我們的返回函數(shù)的。而此時(shí),我們函數(shù)內(nèi)的變量只能有一個(gè)值。

​ 但是,我們可以使用另一個(gè)辦法來規(guī)避這種情況:

def outerFunction(x): #外函數(shù)
    L=[] #定義一個(gè)List 
    y = 10
    def innerFunction(i): #內(nèi)函數(shù)
        def f():
            return (x + y) * i #使用我們外函數(shù)得變量
        return f
    for i in range(1, 4):
        print(innerFunction(i)()) #打印內(nèi)函數(shù)中的內(nèi)函數(shù)的返回值
        L.append(innerFunction(i)) #把內(nèi)函數(shù)添加到我們得List中
    return L #返回這個(gè)List
a = outerFunction(10)
print(a[0])
print(a[1])
print(a[2])
print(a[0]())
print(a[1]())
print(a[2]())

​ 打印如下:

20
40
60
<function outerFunction.<locals>.innerFunction.<locals>.f at 0x00000155B0F80040>
<function outerFunction.<locals>.innerFunction.<locals>.f at 0x00000155B0F803A0>
<function outerFunction.<locals>.innerFunction.<locals>.f at 0x00000155B0F80430>
20
40
60

​ 這里我們可以看到我們?cè)谕獠空{(diào)用的時(shí)候,函數(shù)的返回值和在內(nèi)部調(diào)用的返回值是一樣的。那么我們分析一下這個(gè)函數(shù)的執(zhí)行過程以及函數(shù)內(nèi)的變量的作用域情況。

​ 首先,我們?cè)谖覀冇捎诘膬?nèi)函數(shù)的基礎(chǔ)又添加了一層內(nèi)函數(shù) f() ,并且,在這個(gè)內(nèi)函數(shù)里面,我們使用了外部的內(nèi)函數(shù) innerFunction 的參數(shù)作為了返回值。然后,我們?cè)?for 循環(huán)內(nèi)部把我們的 innerFunction 這個(gè)函數(shù)的返回值添加進(jìn)來我們的 List 里面。

​ 這里我們應(yīng)該已經(jīng)發(fā)現(xiàn)了。在 for 循環(huán)內(nèi)部,當(dāng)我們把 innerFunction 的返回值 f 添加到我們的 List 中的時(shí)候,由于 innerFunction 相對(duì)于函數(shù) f() 而言,f() 是屬于 innerFunction 的內(nèi)函數(shù)的,因此,當(dāng)我們返回 f() 這個(gè)函數(shù)的時(shí)候,此時(shí),f() 函數(shù)內(nèi)部使用的值就是它的最終值了,而此時(shí),我們的 innerFunction 函數(shù)還在 for 循環(huán)內(nèi)部,因此,在循環(huán)內(nèi)部,每次調(diào)用我們的 innerFunction 的返回值時(shí),我們的傳遞到我們的 f() 函數(shù)中的值就是我們的最終值了。

​ 此時(shí),即使是我們?cè)谕獠空{(diào)用這個(gè) f() 函數(shù),它返回的值和內(nèi)部調(diào)用時(shí)也是一樣的。

以上就是Python編程中閉包的變量作用域問題解析的詳細(xì)內(nèi)容,更多關(guān)于Python閉包中變量作用域的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python中for循環(huán)把字符串或者字典添加到列表的方法

    python中for循環(huán)把字符串或者字典添加到列表的方法

    今天小編就為大家分享一篇python中for循環(huán)把字符串或者字典添加到列表的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Qt通過QGraphicsview實(shí)現(xiàn)簡單縮放及還原效果

    Qt通過QGraphicsview實(shí)現(xiàn)簡單縮放及還原效果

    本文主要介紹通過QGraphicsview實(shí)現(xiàn)簡單的縮放以及縮放后還原原始大小,通過scale可以對(duì)view進(jìn)行放大或縮小,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-09-09
  • Python爬蟲之Selenium警告框(彈窗)處理

    Python爬蟲之Selenium警告框(彈窗)處理

    這篇文章主要介紹了Python爬蟲之Selenium警告框(彈窗)處理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • python Tornado事件循環(huán)示例源碼解析

    python Tornado事件循環(huán)示例源碼解析

    這篇文章主要為大家介紹了python Tornado事件循環(huán)示例源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • pandas改變df列的順序的方法實(shí)現(xiàn)

    pandas改變df列的順序的方法實(shí)現(xiàn)

    本文主要介紹了pandas改變df列的順序的方法實(shí)現(xiàn),主要使用 Pandas 中的 reindex() 方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • tensorflow:指定gpu 限制使用量百分比,設(shè)置最小使用量的實(shí)現(xiàn)

    tensorflow:指定gpu 限制使用量百分比,設(shè)置最小使用量的實(shí)現(xiàn)

    今天小編就為大家分享一篇tensorflow:指定gpu 限制使用量百分比,設(shè)置最小使用量的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • 基于Python實(shí)現(xiàn)批量保存視頻到本地

    基于Python實(shí)現(xiàn)批量保存視頻到本地

    我們刷視頻時(shí)常常會(huì)想把精彩的視頻保存到本地,如果少數(shù)的還行,如果有很多的話一個(gè)個(gè)保存太麻煩了。本文教你如何用Python實(shí)現(xiàn)視頻批量保存到本地,需要的可以參考一下
    2022-05-05
  • python實(shí)現(xiàn)嵌套列表平鋪的兩種方法

    python實(shí)現(xiàn)嵌套列表平鋪的兩種方法

    今天小編就為大家分享一篇python實(shí)現(xiàn)嵌套列表平鋪的兩種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python常用擴(kuò)展插件使用教程解析

    Python常用擴(kuò)展插件使用教程解析

    這篇文章主要介紹了Python常用擴(kuò)展插件使用教程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Python 敏感詞過濾的實(shí)現(xiàn)示例

    Python 敏感詞過濾的實(shí)現(xiàn)示例

    本文主要介紹了Python 敏感詞過濾的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08

最新評(píng)論

临湘市| 浦县| 永善县| 星子县| 洛隆县| 饶阳县| 漯河市| 青神县| 桓仁| 高邮市| 恩施市| 韶关市| 江口县| 盈江县| 临西县| 三河市| 怀安县| 浪卡子县| 和田市| 定西市| 布拖县| 临湘市| 唐河县| 永年县| 高雄县| 师宗县| 毕节市| 开平市| 怀集县| 卢氏县| 淮安市| 河曲县| 平山县| 漳浦县| 河北省| 海口市| 衡阳市| 定边县| 河池市| 锦州市| 遂川县|