今天小編給大家分享一下Python函數(shù)進(jìn)階的使用方法實例分析的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
創(chuàng)新互聯(lián)建站是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計,網(wǎng)站模板,微信公眾號開發(fā),軟件開發(fā),微信平臺小程序開發(fā),10多年建站對酒樓設(shè)計等多個行業(yè),擁有豐富的網(wǎng)站推廣經(jīng)驗。
假如有一串代碼,觀察其輸出結(jié)果:
def f(): a = 1 return a print(a) 輸出結(jié)果: Traceback (most recent call last): File "E:/python代碼/11/文件一.py", line 4, in <module> print(a) NameError: name 'a' is not defined報錯了!錯誤是“name 'a' is not defined”。變量a沒有被定義。。。為啥?我明明定義了a=1呀!
那我們就要了解一下Python代碼運行時遇到函數(shù)時怎么做的:
首先從python解釋器開始執(zhí)行之后,就在內(nèi)存中開辟了一個空間每當(dāng)遇到一個變量的時候,就把變量名和值之間的對應(yīng)關(guān)系記錄下來。但是當(dāng)遇到函數(shù)定義的時候解釋器只是象征性的將函數(shù)名讀入內(nèi)存,表示知道這個函數(shù)的存在了,至于函數(shù)內(nèi)部的變量和邏輯解釋器根本不關(guān)心。等執(zhí)行到函數(shù)調(diào)用的時候,python解釋器會再開辟一塊內(nèi)存來存儲這個函數(shù)里的內(nèi)容,這個時候,才關(guān)注函數(shù)里面有哪些變量,而函數(shù)中的變量會存儲在新開辟出來的內(nèi)存中。函數(shù)中的變量只能在函數(shù)的內(nèi)部使用,并且會隨著函數(shù)執(zhí)行完畢,這塊內(nèi)存中的所有內(nèi)容也會被清空。
我們給這個“存放名字與值的關(guān)系”的空間起了一個名字——叫做命名空間
代碼在最開始創(chuàng)建的存儲“變量名與值的關(guān)系”的空間叫做全局命名空間,在函數(shù)內(nèi)部運行中開辟的臨時的空間叫做局部命名空間
函數(shù)命名空間一共分為三大類
1、內(nèi)置命名空間 —— python解釋器 # 就是python解釋器一啟動就可以使用的名字存儲在內(nèi)置命名空間中 # 內(nèi)置的名字在啟動解釋器的時候被加載進(jìn)內(nèi)存里 2、全局命名空間 —— 我們寫的代碼但不是函數(shù)中的代碼 # 是在程序從上到下被執(zhí)行的過程中依次加載進(jìn)內(nèi)存的 # 放置了我們設(shè)置的所有變量名和函數(shù)名 3、局部命名空間 —— 函數(shù) # 就是函數(shù)內(nèi)部定義的名字 # 當(dāng)調(diào)用函數(shù)的時候 才會產(chǎn)生這個名稱空間 隨著函數(shù)執(zhí)行的結(jié)束 這個命名空間就又消失了 #在局部:可以使用全局、內(nèi)置命名空間中的名字 #在全局:可以使用內(nèi)置命名空間中的名字,但是不能用局部中使用 #在內(nèi)置:不能使用局部和全局的名字的內(nèi)置命名空間:內(nèi)置命名空間中存放了Python解釋器為我們提供的名字(函數(shù))我們不需要定義,都是我們熟悉的打開解釋器就能夠直接使用如:input、print、str、set……
加載順序:內(nèi)置命名空間(程序運行前加載 > 全局命名空間(程序運行中:從上到下加載) > 局部命名空間(程序運行中:調(diào)用時才加載)
在局部調(diào)用時:局部命名空間 > 全局命名空間 > 內(nèi)置命名空間
在全局調(diào)用時:全局命名空間 > 內(nèi)置命名空間
例子:
a = 10 def f(): a = 1 print(a) f() print(a) 輸出結(jié)果: 1 10
作用域就是作用范圍,按照生效范圍可以分為全局作用域和局部作用域。
全局作用域:包含內(nèi)置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效
局部作用域:局部名稱空間,只能在局部范圍內(nèi)生效
locals():
函數(shù)會以字典類型返回當(dāng)前位置的全部局部變量。globals():
函數(shù)會以字典類型返回當(dāng)前位置的全部全局變量。def func(): a = 1 print(locals()) print(globals()) print('========================分割線==========================') func() print(locals()) print(globals())輸出結(jié)果:
1、global是Python中的全局變量關(guān)鍵字。
2、變量分為局部變量與全局變量,局部變量又可稱之為內(nèi)部變量。
3、由某對象或某個函數(shù)所創(chuàng)建的變量通常都是局部變量,只能被內(nèi)部引用,而無法被其它對象或函數(shù)引用。
4、全局變量既可以是某對象函數(shù)創(chuàng)建,也可以是在本程序任何地方創(chuàng)建。全局變量是可以被本程序所有對象或函數(shù)引用。
5、global關(guān)鍵字的作用是可以使得一個局部變量為全局變量例子:
在my函數(shù)中,在 x 前面加 global,my函數(shù)將 x 賦為8,此時全局變量中的 x 值改變。需要注意的是 global 需要在函數(shù)內(nèi)部聲明,若在函數(shù)外聲明,則函數(shù)依然無法操作 x 。
x = 4 def my(): global x x = 8 print("x = ", x) print("x = ", x) my() print("x = ", x) 輸出結(jié)果是: x = 4 x = 8 x = 8
def max2(x,y): m = x if x>y else y return m def max4(a,b,c,d): res1 = max2(a,b) res2 = max2(res1,c) res3 = max2(res2,d) return res3 ret = max4(1,2,4,3) print(ret) 輸出結(jié)果: 4
def f1(): print("in f1") def f2(): print("in f2") f2() f1() 輸出結(jié)果: in f1 in f2 def f1(): def f2(): def f3(): print("in f3") print("in f2") f3() print("in f1") f2() f1() 輸出結(jié)果: in f1 in f2 in f3
a = 1 def outer(): a = 5 def inner(): a = 2 def inner2(): nonlocal a a += 1 print('inner2',a) inner2() print('##a##:',a) inner() print('**a**:',a) outer() print('全局:',a) 輸出結(jié)果: inner2 3 ##a##: 3 **a**: 5 全局: 1
#nonlocal 只能用于局部變量,找上層中離當(dāng)前函數(shù)最近一層的局部變量且外部必須有這個變量 #聲明了nonlocal的內(nèi)部函數(shù)的變量修改會影響到離當(dāng)前函數(shù)最近一層的局部變量 #對全局無效,在內(nèi)部函數(shù)聲明nonlocal變量之前不能再出現(xiàn)同名變量 #對局部也只是對最近一層有影響def f1(): a = 1 def f2(): nonlocal a a = 2 f2() print('a in f1 : ',a) f1() 輸出結(jié)果: a in f1 : 2
# 對于不可變數(shù)據(jù)類型 在局部可是查看全局作用域中的變量 # 但是不能直接修改 # 如果想要修改,需要在程序的一開始添加global聲明 # 如果在一個局部(函數(shù))內(nèi)聲明了一個global變量,那么這個變量在局部的所有操作將對全局的變量有效
函數(shù)名就是內(nèi)存地址
函數(shù)名可以被賦值
函數(shù)名可以作為容器類型的元素
函數(shù)名可以作為函數(shù)的返回值
函數(shù)名可以作為函數(shù)的參數(shù)
def func(): print(123) func() print(func) # 函數(shù)名就是內(nèi)存地址 # 函數(shù)名可以被賦值 func2 = func func2() #函數(shù)名可以作為容器類型的元素 l = [func,func2] for i in l: i() def func(): print(123) def wahaha(f): f() return f #函數(shù)名可以作為函數(shù)的返回值 qqxing = wahaha(func) #函數(shù)名可以作為函數(shù)的參數(shù) qqxing() 輸出結(jié)果: 123 <function func at 0x000001ADF9946280> 123 123 123 123 123
如果我自己定義了一個input函數(shù)(作用:調(diào)用該函數(shù)就打印'在下周周ovo'),會不會與內(nèi)置的input函數(shù)有沖突呢?
def input(a): print('在下周周ovo')那么接下來的代碼怎么運行呢?
def input(a): print('在下周周ovo') def func(): input('請輸入') print(input) func()答案:
內(nèi)部函數(shù)包含對外部作用域而非全劇作用域名字的引用,該內(nèi)部函數(shù)稱為閉包函數(shù)
#函數(shù)內(nèi)部定義的函數(shù)稱為內(nèi)部函數(shù)由于有了作用域的關(guān)系,我們就不能拿到函數(shù)內(nèi)部的變量和函數(shù)了。如果我們就是想拿怎么辦呢?返回呀!
如果函數(shù)內(nèi)的變量我們要想在函數(shù)外部用,可以直接返回這個變量,那么如果我們想在函數(shù)外部調(diào)用函數(shù)內(nèi)部的函數(shù)呢?那就直接將函數(shù)名字作為返回值就好
def outer(): a = 1 def inner(): print(a) #內(nèi)部函數(shù)調(diào)用了外部變量a return inner inn = outer() inn() 輸出結(jié)果: 1
判斷閉包函數(shù)的方法__closure__
當(dāng)運行后,如果有cell的話,就表示是閉包函數(shù)。如果沒有就不是。
#輸出的__closure__有cell元素 :是閉包函數(shù) def func(): name = 'eva' def inner(): print(name) print(inner.__closure__) return inner f = func() f() #輸出的__closure__為None :不是閉包函數(shù) name = 'egon' def func2(): def inner(): print(name) print(inner.__closure__) return inner f2 = func2() f2() 輸出結(jié)果: (<cell at 0x000001E935CB0FA0: str object at 0x000001E935CC2CB0>,) eva None egon
顧名思義是兩個或以上的閉包函數(shù)嵌套在一起
def wrapper(): money = 10 def func(): name = 'zhou' def inner(): print(name,money) #引用了func()函數(shù)中name變量引用了wrapper()函數(shù)中money變量 return inner return func f = wrapper() i = f() i() 輸出結(jié)果: zhuo 10
#func(一個函數(shù)名) --->>對應(yīng)函數(shù)的內(nèi)存地址 #函數(shù)名()---函數(shù)調(diào)用 #函數(shù)的內(nèi)存地址----()函數(shù)的調(diào)用 # 作用域兩種 # 全局作用域 —— 作用在全局 —— 內(nèi)置和全局名字空間中的名字都屬于全局作用域 ——globals() # 局部作用域 —— 作用在局部 —— 函數(shù)(局部名字空間中的名字屬于局部作用域) ——#locals()globals() : 永遠(yuǎn)打印全局的名字 #locals() : 輸出什么 根據(jù)locals所在位置 #在代碼中要盡量少定義全局變量,多使用返回值和接收返回值 #函數(shù)的嵌套: 嵌套調(diào)用 嵌套定義:定義在內(nèi)部的函數(shù)無法直接在全局被調(diào)用 #函數(shù)名的本質(zhì): 就是一個變量,保存了函數(shù)所在的內(nèi)存地址 #閉包: 內(nèi)部函數(shù)包含對外部作用域而非全劇作用域名字的引用,該內(nèi)部函數(shù)稱為閉包函數(shù)
以上就是“Python函數(shù)進(jìn)階的使用方法實例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享名稱:Python函數(shù)進(jìn)階的使用方法實例分析
URL標(biāo)題:http://muchs.cn/article12/gjchgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、Google、ChatGPT、網(wǎng)站內(nèi)鏈、網(wǎng)站收錄、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)