您好,登錄后才能下訂單哦!
這篇文章主要介紹“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函數嵌套怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。