亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關于Python中的閉包詳解

 更新時間:2022年01月27日 17:09:58   作者:繁華似錦Fighting  
大家好,本篇文章主要講的是關于Python中的閉包詳解,感興趣的同學感快來看一看吧,對你有幫助的話記得收藏一下

1、閉包的概念

請大家跟我理解一下,如果在一個函數的內部定義了另一個函數,外部的我們叫他外函數,內部的我們叫他內函數。閉包: 在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用。這樣就構成了一個閉包。一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。但是閉包是一種特殊情況,如果外函數在結束的時候發(fā)現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給了內部函數,然后自己再結束。

2、實現一個閉包

# 將函數作為返回值返回,也是一種高階函數
# 這種高階函數我們也稱為叫做閉包,通過閉包可以創(chuàng)建一些只有當前函數能訪問的變量
#   可以將一些私有的數據藏到的閉包中

def outer():
    a = 10

    # 函數內部再定義一個函數
    def inner():
        print('我是outer', a)

    # 將內部函數 inner作為返回值返回
    return inner


# r是一個函數對象,是調用fn()后返回的函數對象
# 這個函數實在fn()內部定義,并不是全局函數
# 所以這個函數總是能訪問到fn()函數內的變量
# 外函數返回了內函數的引用
fn = outer()

# r()相當于調用了inner()函數
print("outer引用地址:", outer)
print("inner引用地址:", fn)
fn()
"""
輸出結果:
outer引用地址: <function outer at 0x0000000002BB5948>
inner引用地址: <function outer.<locals>.inner at 0x0000000002BB58B8>
我是outer 10
"""

說明上述代碼:

對于閉包,在外函數outer中 最后return inner,我們在調用外函數 fn = outer() 的時候,outer函數返回了inner函數對象,inner函數對象是一個函數的引用,這個引用被存入了fn對象中。所以接下來我們再進行fn() 的時候,相當于運行了inner函數。

提示:

一個函數,如果函數名后緊跟一對括號,相當于調用這個函數。如果不跟括號,相當于只是一個函數的名字,里面存了函數所在位置的引用。

3、在閉包中外函數把臨時變量綁定給內函數

按照我們正常的認知,一個函數結束的時候,會把自己的臨時變量都釋放還給內存,之后變量都不存在了。一般情況下,確實是這樣的。但是閉包是一個特別的情況。外部函數發(fā)現,自己的臨時變量會在將來的內部函數中用到,自己在結束的時候,返回內函數的同時,會把外函數的臨時變量送給內函數綁定在一起。所以外函數已經結束了,調用內函數的時候仍然能夠使用外函數的臨時變量。

在我編寫的實例中,我兩次調用外部函數outer,分別傳入的值是10和20。內部函數只定義了一次,我們發(fā)現調用的時候,內部函數是能識別外函數的臨時變量是不一樣的。

Python中一切都是對象,雖然函數我們只定義了一次,但是外函數在運行的時候,實際上是按照里面代碼執(zhí)行的,外函數里創(chuàng)建了一個函數,我們每次調用外函數,它都創(chuàng)建一個內函數,雖然代碼一樣,但是卻創(chuàng)建了不同的對象,并且把每次傳入的臨時變量數值綁定給內函數,再把內函數引用返回。

所以我們每次調用外函數,都返回不同的實例對象的引用,他們的功能是一樣的,但是它們實際上不是同一個函數對象。

下面示例進行演示:

def outer(num):
    a = num

    # 函數內部再定義一個函數
    def inner():
        print('我是outer', a)

    # 將內部函數 inner作為返回值返回
    return inner


fn1 = outer(10)
fn2 = outer(20)


print("inner引用地址:", fn1)
fn1()
print("inner引用地址:", fn2)
fn2()
"""
輸出結果:
inner引用地址: <function outer.<locals>.inner at 0x00000000026B58B8>
我是outer 10
inner引用地址: <function outer.<locals>.inner at 0x00000000026B5828>
我是outer 20
"""
# 注意兩個inner的地址不一樣,一個是8B8,一個是828。

4、閉包中內函數修改外函數局部變量

在基本的Python語法當中,一個函數可以隨意讀取全局數據,但是要修改全局數據的時候有兩種方法

global聲明全局變量。全局變量是可變類型數據的時候可以修改。

在閉包內函數也是類似的情況。在內函數中想修改閉包變量(外函數綁定給內函數的局部變量)的時候,在Python3中,可以用nonlocal關鍵字聲明一個變量, 表示這個變量不是局部變量空間的變量,需要向上一層變量空間找這個變量。

示例:

def outer(num):
    a = num
    b = 10  # a和b都是閉包變量
    print("原始a值為", a)

    # inner內函數
    def inner():
        # 內函數中想修改閉包變量
        # nonlocal關鍵字聲明變量
        nonlocal a
        a += b
        print('我是outer的a', a)

    # 將內部函數 inner作為返回值返回
    return inner


fn1 = outer(10)

fn1()
"""
輸出結果:
原始a值為 10
我是outer的a 20
"""

在內函數中,對閉包變量進行了修改,打印出來的結果也確實是修改之后的結果。

5、注意:

還有一點需要注意,閉包變量實際上只有一份,每次調用一份閉包變量。(這個在Python實現的單利模式下來解釋更多)

def outer(num):
    a = num
    b = 10  # a和b都是閉包變量
    print("原始a值為", a)

    # inner內函數
    def inner():
        # 內函數中想修改閉包變量
        # nonlocal關鍵字聲明變量
        nonlocal a
        a += b
        print('我是outer的a', a)

    # 將內部函數 inner作為返回值返回
    return inner


fn1 = outer(10)

fn1()
fn1()
fn1()
"""
輸出結果:
原始a值為 10
我是outer的a 20
我是outer的a 30
我是outer的a 40
"""

可以看到第二次第二次調用fn1()方法,a的值有增加了10。

6、練習:

# 求多個數的平均值
# nums = [50,30,20,10,77]

# sum()是一個求和函數
# sum()用來求一個列表中所有元素的和
# print(sum(nums)/len(nums))
# 結果:37.4


# 形成閉包的要件
#   ① 函數嵌套
#   ② 將內部函數作為返回值返回
#   ③ 內部函數必須要使用到外部函數的變量


def make_averager():
    # 創(chuàng)建一個列表,用來保存數值
    nums = []

    # 創(chuàng)建一個函數,用來計算平均值
    def averager(n) :
        # 將n添加到列表中
        nums.append(n)
        # 求平均值
        return sum(nums)/len(nums)

    return averager

# 創(chuàng)建對象,現在就是獲得了內函數對象的引用
averager = make_averager()

# 調用內涵書對象
# 這里注意,雖然是調用外函數創(chuàng)建的對象,
# 但是獲得的是內函數對象的引用,內函數是有形參的,
# 所以averager對象相當于是內函數對象。
# 所以調用內函數就要傳遞形參。
print(averager(10))
print(averager(20))
print(averager(30))
print(averager(40))

總結

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

相關文章

  • python中csv文件創(chuàng)建、讀取及修改等操作實例

    python中csv文件創(chuàng)建、讀取及修改等操作實例

    很多程序在處理數據時都會碰到csv這種格式的文件,下面這篇文章主要給大家介紹了關于python中csv文件創(chuàng)建、讀取及修改等操作的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • Python argparse 解析命令行參數模塊詳情

    Python argparse 解析命令行參數模塊詳情

    這篇文章主要介紹了Python argparse 解析命令行參數模塊詳情,argparse是python用于解析命令行參數和選項的標準模塊,用于代替已經過時的optparse模塊
    2022-07-07
  • python獲取網絡圖片方法及整理過程詳解

    python獲取網絡圖片方法及整理過程詳解

    這篇文章主要介紹了python獲取網絡圖片方法及整理過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 詳解如何設置Python環(huán)境變量?

    詳解如何設置Python環(huán)境變量?

    這篇文章主要介紹了如何設置Python環(huán)境變量?,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • python使用turtle庫寫六角形的思路與代碼

    python使用turtle庫寫六角形的思路與代碼

    學習Python,接觸到turtle包,就用它來畫一下六邊形,下面這篇文章主要給大家介紹了關于python使用turtle庫寫六角形的思路與代碼,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • 關于pyinstaller生成.exe程序報錯:缺少.ini文件的分析

    關于pyinstaller生成.exe程序報錯:缺少.ini文件的分析

    這篇文章主要介紹了關于pyinstaller生成.exe程序報錯:缺少.ini文件的分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • python檢測IP地址變化并觸發(fā)事件

    python檢測IP地址變化并觸發(fā)事件

    這篇文章主要為大家詳細介紹了python檢測IP地址變化并觸發(fā)事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 詳解Python中的相對導入和絕對導入

    詳解Python中的相對導入和絕對導入

    絕對導入是指跳過包內,直接搜索 sys.path ,在sys.path的基礎上進行我們的模塊搜索。相對導入是指先包內,再包外,再,,,那么下面這篇文章主要給大家介紹了Python中的相對導入和絕對導入,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • Python高階函數map()?簡介和使用詳解

    Python高階函數map()?簡介和使用詳解

    map()?函數是Python中的內置函數,這個函數又叫做映射函數,其實里面具有一個迭代器的功能,會依次遍歷可迭代對象進行相關的操作,這篇文章主要介紹了Python高階函數map()?簡介和使用詳解,需要的朋友可以參考下
    2023-03-03
  • Python OS模塊常用函數說明

    Python OS模塊常用函數說明

    這篇文章主要介紹了Python OS模塊常用函數說明,本文列出了一些在os模塊中比較有用的部分函數,它們中的大多數都簡單明了,需要的朋友可以參考下
    2015-05-05

最新評論