python中的函數(shù)嵌套和嵌套調(diào)用
函數(shù)嵌套和嵌套調(diào)用
函數(shù)的嵌套
函數(shù)的嵌套:在函數(shù)里面還有函數(shù)。分為外函數(shù)和內(nèi)函數(shù)。
嵌套函數(shù)是為函數(shù)內(nèi)部服務(wù)的,比如減少代碼的重復(fù),想要調(diào)用函數(shù),要使用函數(shù)名,內(nèi)函數(shù)也一樣。如果不用函數(shù)名調(diào)用內(nèi)函數(shù),內(nèi)函數(shù)就永遠不會執(zhí)行。
內(nèi)函數(shù)的調(diào)用
怎么在函數(shù)外部調(diào)用內(nèi)函數(shù)呢?首先,不能直接調(diào)用內(nèi)函數(shù) ,需要先執(zhí)行外函數(shù)的代碼塊。
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") func2() ?
沒有執(zhí)行外函數(shù)內(nèi)部的代碼塊,python找不到內(nèi)函數(shù),所以報name ‘func2’ is not defined,函數(shù)func2()沒有定義
有幾種方式可以實現(xiàn)對內(nèi)函數(shù)的調(diào)用。
1.在外函數(shù)內(nèi)部調(diào)用內(nèi)函數(shù),即用函數(shù)名調(diào)用
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") ?? ?func2() #函數(shù)名調(diào)用內(nèi)函數(shù) func1()?
這樣調(diào)用外函數(shù)也會執(zhí)行內(nèi)函數(shù)的代碼塊了
2.可以用return調(diào)用內(nèi)函數(shù)
在使用return之前,需要說明一點:我們都是使用"函數(shù)名()“調(diào)用函數(shù)的方法,單獨使用"函數(shù)名”,我們會得到函數(shù)的內(nèi)存地址;(函數(shù)名后面加括號才會告訴python,參數(shù)是否對得上,然后執(zhí)行函數(shù)的代碼塊。)
- "return函數(shù)名()"調(diào)用內(nèi)函數(shù)
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") ?? ?return func2() func1()
函數(shù)沒有返回值,即返回值為None,"return func2()"和"func2()"的效果是一樣的
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") ?? ?return func2() m = func1() #調(diào)用函數(shù)func1(),調(diào)用函數(shù)func2的方法 print(m) ? ?#m為None
- 外函數(shù)內(nèi)部"return函數(shù)名",也可以調(diào)用內(nèi)函數(shù),只不過調(diào)用外函數(shù)時多加一個括號
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") ?? ?return func2 m = func1()? print(m) #? #執(zhí)行結(jié)果為 這是外部函數(shù) <function func1.<locals>.func2 at 0x0000000002EB6620>
上面可以看到,使用函數(shù)名得到的是函數(shù)的地址,我們可以用一個變量指向這個地址,相當(dāng)于創(chuàng)建一個變量,這個變量指向的是函數(shù)的地址。因為只有函數(shù)名是不能調(diào)用函數(shù)的方法的,所以調(diào)用外函數(shù)時要用到雙括號。
def func1(): ?? ?print("這是外部函數(shù)") ?? ?def func2(): ?? ??? ?print("這是內(nèi)部函數(shù)") ?? ?return func2 func1()() ##執(zhí)行func1()會返回func2然后再func2() # m = func1() # m()
我們可以用func1()返回一個函數(shù)func2,再加一個括號調(diào)用內(nèi)函數(shù)的方法。
小結(jié):想要調(diào)用內(nèi)函數(shù),首先要調(diào)用外函數(shù),即執(zhí)行外函數(shù)的代碼塊,才有內(nèi)函數(shù)調(diào)用的環(huán)境。在外函數(shù)內(nèi)部,可以用函數(shù)名調(diào)用內(nèi)函數(shù)。也可以用return調(diào)用內(nèi)函數(shù),如果return是函數(shù)本身的地址,調(diào)用外函數(shù)時會用到雙括號,先調(diào)用func1()得到func2然后再func2()。如果return func2(),那么和func2()是一樣的,都是告訴python調(diào)用內(nèi)函數(shù)。
變量的作用范圍
外函數(shù)里面的變量和內(nèi)函數(shù)里面的變量是有區(qū)別的,作用范圍不一樣。內(nèi)函數(shù)也可以使用外函數(shù)的變量,但是如果想要在內(nèi)部函數(shù)修改外部函數(shù)變量的值,就要使用關(guān)鍵字nonlocal
def func1(): ?? ?b = 2 ?? ?def func2(): ?? ??? ?nonlocal b ?? ??? ?b = b - 1 ?? ?func2() ?? ?print(b)
函數(shù)的嵌套調(diào)用
在一個函數(shù)里面調(diào)用別的函數(shù)
def print1(): ?? ?print("這是第一個函數(shù)") def print2(): ?? ?print("這是定義的第二個函數(shù)") ?? ?print1() #在print2()中調(diào)用print1() print2()
函數(shù)中定義函數(shù)
在函數(shù)內(nèi)部定義的函數(shù)要在函數(shù)內(nèi)部調(diào)用
def paint(): ? ? print("paint") ? ? def paintA(): ? ? ? ? print("paintA") ? ? paintA() paint() //輸出如下: //paint //paintA
在函數(shù)外部調(diào)用函數(shù)的結(jié)果如下
paintA //試圖在函數(shù)外部調(diào)用paintA()
//以下是報錯信息
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-15-1a59d6e3eeb5> in <module>()
5 paintA()
6 paint()
----> 7 paintANameError: name 'paintA' is not defined
函數(shù)內(nèi)的函數(shù)可以引用外部變量
但是不可以對其進行修改
a=6 def FuncX(x): ? ? ?def FuncY(y): ? ? ? ? ? ? ?return a*y ? ? ? ? ? ? // return x*y,這里也可以寫這條語句進行測試,因為對于FuncY()來說,x也算外部變量,我這里主要是為了突出外部變量這個概念 ? ? ?return FuncY FuncX(5)(6)//把5賦給x,6賦給y //輸出結(jié)果如下: 36
試圖對外部變量進行修改
a=6 def FuncX(x): ? ? ?def FuncY(y): ? ? ? ? ? ? #global a ? ?加上這條語句即可修改a的值 ? ? ? ? ? ? ?a=a*y ? ? ? ? ? ? ?return a ?#試圖修改 a 的值 ? ? ? ? ? ?#return a=a*y ? Python不允許返回賦值表達式,并不是因為修改a的原因,這里更新一下 ? ? ? ? ? ?#更新時間 ?2019.1.4 ? ? ? ? ? ? ? ? ? ? ?return FuncY FuncX(5)(6) //報錯信息 UnboundLocalError: local variable 'a' referenced before assignment
函數(shù)怎么修改外部變量的值的說明
對于全局變量的修改,如果全局變量是int或者str,那么如果想要在函數(shù)中對函數(shù)變量進行修改,則需要先在函數(shù)內(nèi),聲明其為global或nonlocal,在進行修改, 如果是list或者dict則可以直接修改
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python模擬投擲色子并數(shù)據(jù)可視化統(tǒng)計圖
這篇文章主要介紹了python模擬投擲色子并數(shù)據(jù)可視化統(tǒng)計圖,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07python基于urllib實現(xiàn)按照百度音樂分類下載mp3的方法
這篇文章主要介紹了python基于urllib實現(xiàn)按照百度音樂分類下載mp3的方法,涉及Python使用urllib模塊操作頁面元素的相關(guān)技巧,需要的朋友可以參考下2015-05-05python Pandas庫基礎(chǔ)分析之時間序列的處理詳解
這篇文章主要介紹了python Pandas庫基礎(chǔ)分析之時間序列的處理詳解,Pandas作為Python環(huán)境下的數(shù)據(jù)分析庫,更是提供了強大的日期數(shù)據(jù)處理的功能,是處理時間序列的利器,需要的朋友可以參考下2019-07-07一文帶你學(xué)會如何利用Python實現(xiàn)一個三維繪圖系統(tǒng)
tkinter是Python標準庫中自帶的GUI工具,使用十分方便,所以本文旨在帶大家學(xué)會如何將matplotlib嵌入到tkinter中并繪制三維繪圖系統(tǒng),感興趣的可以了解下2023-09-09python實現(xiàn)socket客戶端和服務(wù)端簡單示例
這篇文章主要介紹了python實現(xiàn)socket客戶端和服務(wù)端簡單示例,需要的朋友可以參考下2014-02-02tensorflow ckpt模型和pb模型獲取節(jié)點名稱,及ckpt轉(zhuǎn)pb模型實例
今天小編就為大家分享一篇tensorflow ckpt模型和pb模型獲取節(jié)點名稱,及ckpt轉(zhuǎn)pb模型實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01