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

溫馨提示×

溫馨提示×

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

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

python函數嵌套怎么使用

發布時間:2021-12-17 17:18:53 來源:億速云 閱讀:206 作者:iii 欄目:大數據

這篇文章主要介紹“python函數嵌套怎么使用”,在日常操作中,相信很多人在python函數嵌套怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”python函數嵌套怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、揭開函數名的真實面目

我們創建一個函數給的命名實際是代表一個內存地址,加上括號才會運行函數中的函數體,如果不加括號,可以自己試一下,輸出的是一個內存地址,這樣看來,他實際上他和一個變量差不多,只不過函數代表了一個功能,因此函數也可以作為參數傳入函數,也可以作為返回值返回。

二、函數嵌套(函數中的函數)

def zhangsan():

    def lisi():

print("我是lisi")

    print("我是zhangsan")

    lisi()

zhangsan()

當我們在zhangsan函數中沒有調用lisi時,我是lisi是不會輸出的。只有在調用的時候才會輸出。以上只是2級嵌套,你可以像列表一樣,多次嵌套。

注意:在嵌套函數中我們內部需要修改外部的變量時不能使用關鍵字global,

global影響的是函數外的全局變量。需要使用nonlocal(python3中),例如:

age =111

def zhangsan():

    age = 18

    def lisi():

nonlocal age 

age +=1

print("lisi的年齡為",age)

    print("zhangsan的年齡為",age)

    lisi()    

zhangsan()

print("age:",age)

我們運行一下會發現,age并沒有影響到函數(zhangsan外)的age。如果換成global,就會影響到全局變量。

三、閉包

例如一個簡單的閉包:

def zhangsan():

    age = 18

    def lisi():

print(age)

    return lisi

閉包的概念:首先它是一個嵌套函數,其次在內部函數中引用了外部函數的變量,我們稱這是一個閉包。

其次我們為什么要以返回值的形式返回lisi,我們可以想一下,如果我們只想用到lisi這個函數,如果我們用二中的方法,每次調用zhangsan,那么每次都要走一遍zhangsan,這顯然不是我們想要的,因此,我們如果只想調用lisi可以這樣寫:wangwu = zhangsan()#此時wangwu代表的就是lisi的內存地址,但并沒有去執行它。wangwu()#這樣就實現調用lisi這個內部函數,并且可以引用到zhangsan中age這個變量。

四、裝飾器

4.1普通裝飾器

首先,思考一個問題,我們進入一個網頁,再點擊個人信息,會提醒需要登錄才能查看,那么需要我們登錄的頁面很多,每次都調用很麻煩,所有就有了裝飾器。

它需要遵循一個原則:開放封閉原則

開放:就是說要有利于擴展新的功能,比如更新的時候。

封閉:在擴展新功能的時候,不能修改原來的代碼。

例如:

def login():

    print("登錄")

def func():

    print("點擊個人信息")

A寫好登錄,B寫好個人信息,C想要調用個人信息他不會去想著調用登錄,B需要將這兩個功能結合起來,但是不能修改原來的功能,于是就有了:

def login(func):

    print("登錄")

    def log():

func()

    return log


def func():

    print("點擊個人信息")

func = login(func)

f()

用閉包的知識可以解決這個問題,func這個方法就叫做裝飾器。但是一想要加上func = login(func)這樣我們就調用的不是原來的函數名了,于是乎就有了:

def login(func):

    print("登錄")

    def log():

func()

    return log

@login

def func():

    print("點擊個人信息")

func()

利用在該函數上方添加一個@加函數名代替func = login(func)。我們稱它為語法糖,嗯,真甜。

現在調用func就相當于調用login了,但是當func函數有返回值的時候,我們按照上述寫法就獲取不到了,因此修改成:

def login(func):

    print("登錄")

    def log():

ret = func()

return ret

    return log

@login

def func():

    print("點擊個人信息")

    return "ok"

print(func())

總結:當我們執行到func()的時候,會跳到@login,@login相當于執行func = login(func),此時就執行login函數了。執行后的結果返回給func,此時func得到的值就是ok的內存地址,再回到func(),便會輸出ok。

問題來了:

當我們新添加的功能,也就是func函數需要一個參數時候在裝飾器函數中如何添加?下一個功能也可能需要這個裝飾器需要二個參數該怎么辦?也是就我們的參數是動態的,那就添加動態參數掰,將login函數修改成:

def login(func):

    print("登錄")

    def log(*args,**kwargs):

ret = func(*args,**kwargs)

return ret

    return log

此時無論添加幾個都不會受到影響。

4.2帶參數的裝飾器

首先如果我們添加一個參數@login(True),當有參數時,我們將@和login(True)拆開看,login(True)得到返回值log函數的內存地址也就是@log,顯然我們的func放在哪里呢?顯然會報錯,于是我們可以在外再嵌套一層變成:

def log_out(F):

    def login(func):

        print("登錄")

        def log(*args,**kwargs):

    if F==True:

        ret = func(*args,**kwargs)

        return ret

    else:

return "NO"

        return log

    return login

@log_out(True)

def func():

    print("點擊個人信息")

    return "ok"

print(func())

這樣再按照之前的理解方式就明白了,log_out(True)表示login也就是@login,

我們只是在原來的基礎上添加了一個開關,也就是說當裝飾器帶參數時,就需要三層嵌套了。

4.3  一個函數使用多個裝飾器

def zhangsan1(fun1):

    def lisi1(*args,**kwargs):

print("執行被裝飾函數前111111")

fun1(*args,**kwargs)

print("執行被裝飾函數后111111")

    return lisi1

def zhangsan2(fun2):

    def lisi2(*args,**kwargs):

print("執行被裝飾函數前222222")

fun2(*args,**kwargs)

print("執行被裝飾函數后222222")

    return lisi2

@zhangsan1 

@zhangsan2 #zhangsan3 = zhangsan2(zhangsan3 )

def zhangsan3():

    print("我是被裝飾的函數333333")

zhangsan3()

執行的結果:

執行被裝飾函數前111111

執行被裝飾函數前222222

我是被裝飾的函數333333

執行被裝飾函數后222222

執行被裝飾函數后111111

執行順序:首先當調用zhangsan3的時候,先執行@zhangsan2,@zhangsan2等同于zhangsan3 = zhangsan2(zhangsan3)也就是返回了lisi2,然后執行@zhangsan1,@zhangsan1等同于zhangsan3 = zhangsan1(lisi2)注意,帶入的函數變成了lisi2,而不是zhangsan3,也就返回lisi1,接下來再加上一個括號執行,也就是執行lisi1中的第一句。#執行被裝飾函數前111111,接著fun1()也就是lisi2(),就會輸出#執行被裝飾函數前222222,回到zhangsan2后,帶入的參數又變成了zhangsan3,所以輸出了#我是被裝飾的函數333333,接著輸出執行被裝飾函數后222222,然后再回到最初調用的地方輸出#執行被裝飾函數后111111。。。。

到此,關于“python函數嵌套怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

夏河县| 吉安县| 长白| 高安市| 来凤县| 中阳县| 石台县| 阿鲁科尔沁旗| 江西省| 蚌埠市| 广元市| 新乐市| 北川| 永丰县| 蓬溪县| 晋江市| 马尔康县| 长岛县| 湖北省| 延庆县| 巩义市| 林周县| 平安县| 南华县| 武功县| 高雄市| 九龙县| 广宁县| 顺昌县| 扎兰屯市| 绩溪县| 聂荣县| 恩平市| 仙游县| 陵水| 玉门市| 丹江口市| 许昌县| 鄂伦春自治旗| 定西市| 克山县|