日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Python嵌套函數(shù)與nonlocal使用詳細(xì)介紹_python

作者:weixin_42576837 ? 更新時(shí)間: 2022-11-02 編程語(yǔ)言

理解閉包之前,我們首先需要理解什么是嵌套函數(shù)(nested functions)以及非局部(nonloca)關(guān)鍵字

嵌套函數(shù)

  • 在另一個(gè)函數(shù)中定義的函數(shù)稱為嵌套函數(shù)。
  • 嵌套函數(shù)可以訪問(wèn) 這個(gè)封閉范圍域內(nèi)的 變量。
  • 在python中,這些非局部變量只可以在他們的作用域范圍內(nèi)訪問(wèn)。

嵌套函數(shù)的例子:

#Python program to illustrate
#nested functions
def outerFunction(text):
    text = text
    #該函數(shù)定義在函數(shù)之內(nèi),作為一個(gè)內(nèi)部函數(shù)
    def innerFunction():
        print(text)
    #out函數(shù)中,調(diào)用這個(gè)內(nèi)部函數(shù)
    innerFunction()
if __name__ == '__main__':
    outerFunction('Hey !')

嵌套函數(shù)中變量的范圍

在一個(gè)函數(shù)中訪問(wèn)全局變量之前已經(jīng)說(shuō)過(guò)了,但是怎么在一個(gè)內(nèi)部函數(shù)中訪問(wèn)外部函數(shù)的變量?

def f1():
    #f1的變量
    s = 'hello'
    def f2():
        #f2()內(nèi)部使用f1的變量
        print(s)
    f2()
f1()

這種訪問(wèn)方式和 函數(shù)內(nèi)訪問(wèn)全局變量很類似。

現(xiàn)在我想要在內(nèi)部函數(shù)改變外部函數(shù)的變量要怎么做?

def f1():
    #f1的變量
    s = 'hello'
    def f2():
        #f2()內(nèi)部試圖改變f1的變量
        s = 'hi hi hi'
        print(s)
    f2()
    print(s)
#調(diào)用f1()
f1()

f2()內(nèi)部通過(guò)s = 'hi hi hi' 試圖將外部函數(shù)的變量值s改變。

但是其實(shí)是在f2()內(nèi)部重新創(chuàng)建了一個(gè)新的變量也叫s,所以完全不會(huì)對(duì)外部的s有影響。

這和函數(shù)內(nèi)部改變?nèi)肿兞渴穷愃频模患?code>global,只是創(chuàng)建了一個(gè)同名變量。

那么同樣使用global行不行?

def f1():
    #f1的變量
    s = 'hello'
    def f2():
        #f2()內(nèi)部試圖使用global改變f1的變量
        global s
        s = 'hi hi hi'	#實(shí)際是在f2()中創(chuàng)建了一個(gè)全局變量
        print(s)
    f2()
    print(s)
#調(diào)用f1()
f1()

結(jié)果是完全沒(méi)有變化的,

global s實(shí)際上是在f2()內(nèi)部聲明s是一個(gè)全局變量,是整個(gè)程序都可以使用的,它和f1()中的s不是同一個(gè)。我們可以在函數(shù)外輸出它:

那么如何通過(guò)內(nèi)部函數(shù)改變外部函數(shù)的變量值呢?其中一種方法是使用nonlocal關(guān)鍵字:

def f1():
    #f1的變量
    s = 'hello'
    def f2():
        #f2()使用nonlocal改變f1的變量
        nonlocal s
        s = 'hi hi hi'
        print(s)
    f2()
    print(s)
#調(diào)用f1()
f1()

在f2()函數(shù)內(nèi)部成功的修改了f1()函數(shù)中的變量s的值

nonlocal

nonlocal 關(guān)鍵字被用來(lái)在最近的范圍域中引用變量, 在局部變量和全局變量上使用不起作用,用于在全局范圍和本地局部范圍之外的另一個(gè)范圍內(nèi)引用變量。nonlocal關(guān)鍵字常常被用在嵌套函數(shù)中引用 父函數(shù)中的變量。

使用nonlocal的優(yōu)點(diǎn)

  • 幫助我們?cè)L問(wèn)上層作用域中的變量
  • 引用的變量被重復(fù)使用,因此該變量的內(nèi)存地址也被重復(fù)適使用,所以可以將局部變量保存在內(nèi)存中

缺點(diǎn)

  • nonloca關(guān)鍵字不可以用來(lái)引用全局變量和局部變量
  • nonloca關(guān)鍵字只能用在嵌套結(jié)構(gòu)中

舉例

使用nonlocal關(guān)鍵字修改父函數(shù)中的變量

def foo():
    name = 'hello'
    def  bar():
        nonlocal name #修改父函數(shù)的變量
        name = 'hi hi'
        print(name)
    #調(diào)用bar()
    bar()
    #父函數(shù)foo()內(nèi)輸出name
    print(name)
#調(diào)用foo()
foo()

如果使用nonlocal 修改全局變量會(huì)怎么樣?

#全局變量
global_name = 'hello'
#外部函數(shù)
def f1():
    #內(nèi)部函數(shù)
    def f2():
        #使用nonlocal 聲明,嘗試使用nonlocal 引用全局變量
        nonlocal global_name
        global_name = 'hi hi'#嘗試 修改 
        print(global_name)
    
    #掉用f2()
    f2()
f1()
print(global_name)

報(bào)錯(cuò)信息顯示:沒(méi)有叫做global_namenonlocal變量,這是因?yàn)椋?/p>

nonlocal是用在嵌套結(jié)構(gòu)中,用來(lái)引用父函數(shù)中的局部變量的,但是父函數(shù)f1()中沒(méi)有叫做global_name的局部變量,對(duì)于函數(shù)外部的全局變量global_name來(lái)說(shuō),使用nonlocal是無(wú)法引用的,所以python解釋器找不到global_name,自然出錯(cuò)。

多層嵌套中的nonlocal

def f1():
    name = 'f1'
    def f2():
        name = 'f2'
        def f3():
            #nonlocal 修改父函數(shù)的變量,即f2()的name
            nonlocal name
            print(name)  #輸出f2  使用的是f2中的name
            name = 'f3' #對(duì)f2中的name修改
            print(name) #輸出f3 修改成功
        f3()
        print(name)#輸出f3,雖然是f2中的name,但是在f3中修改了
    f2()
    print(name)#輸出f1,f1的name,沒(méi)有被使用
f1()

所以在多層嵌套的結(jié)構(gòu)成,nonlocal關(guān)鍵字會(huì)尋找最近的上層,也就是父函數(shù),而不是更上層的爺爺函數(shù)。

嵌套函數(shù)中局部變量的重用

def counter():
    #c是局部變量
    c = 0
    def count():
        #使用上層函數(shù)中的c
        nonlocal c
        c += 1
        return c
    return count

調(diào)用外部counter()函數(shù),正常來(lái)說(shuō),函數(shù)調(diào)用結(jié)束后,內(nèi)部的局部變量會(huì)被銷毀,但是由于counter()內(nèi)部嵌套的count()使用了nonlocal來(lái)使用父函數(shù)的局部變量c,所以c是被重用了,即使外層函數(shù)調(diào)用結(jié)束了,c并沒(méi)有被銷毀。

參考:

Python Inner Functions

Python nonlocal Keyword

原文鏈接:https://blog.csdn.net/weixin_42576837/article/details/125530032

欄目分類
最近更新