Python中變量的作用域詳解
1、作用于的概念
變量作用域指的是變量生效的范圍,在Python中一共有兩種作用域。
全局作用域
全局作用域在程序執(zhí)行時(shí)創(chuàng)建,在程序執(zhí)行結(jié)束時(shí)銷毀。所有函數(shù)以外的區(qū)域都是全局作用域。在全局作用域中定義的變量,都屬于全局變量,全局變量可以在程序的任意位置被訪問。
函數(shù)作用域
函數(shù)作用域在函數(shù)調(diào)用時(shí)創(chuàng)建,在調(diào)用結(jié)束時(shí)銷毀。函數(shù)每調(diào)用一次就會(huì)產(chǎn)生一個(gè)新的函數(shù)作用域(不調(diào)用不產(chǎn)生)。在函數(shù)作用域中定義的變量,都是局部變量,它只能在函數(shù)內(nèi)部被訪問。
2、局部變量
所謂局部變量是定義在函數(shù)體內(nèi)部的變量,即只在函數(shù)體內(nèi)部生效。
def testA(): # 局部變量a # 在函數(shù)中為變量賦值時(shí),默認(rèn)都是為局部變量賦值 # 局部變量不會(huì)影響函數(shù)外的變量。 a = 100 # 函數(shù)體內(nèi)部訪問,能訪問到a變量 print(a) testA() # 100 print(a) # 報(bào)錯(cuò):name 'a' is not defined
變量a
是定義在testA
函數(shù)內(nèi)部的變量,在函數(shù)外部訪問則立即報(bào)錯(cuò)。
局部變量的作用:在函數(shù)體內(nèi)部,臨時(shí)保存數(shù)據(jù),即當(dāng)函數(shù)調(diào)用完成后,則銷毀局部變量。
3、全局變量
所謂全局變量,指的是在函數(shù)體內(nèi)、外都能生效的變量。
思考:如果有一個(gè)數(shù)據(jù),在函數(shù)A
和函數(shù)B
中都要使用,該怎么辦?
答:將這個(gè)數(shù)據(jù)存儲(chǔ)在一個(gè)全局變量里面。
# 定義全局變量a a = 100 def testA(): print(a) # 訪問全局變量a,并打印變量a存儲(chǔ)的數(shù)據(jù) def testB(): print(a) # 訪問全局變量a,并打印變量a存儲(chǔ)的數(shù)據(jù) testA() # 100 testB() # 100
思考:testB
函數(shù)需求修改變量a
的值為200,如何修改程序?
a = 100 def testA(): print(a) def testB(): a = 200 print(a) testA() # 100 testB() # 200 print(f'全局變量a = {a}') # 全局變量a = 100
思考:在testB
函數(shù)內(nèi)部的a = 200
中的變量a
是在修改全局變量a
嗎?
答:不是。觀察上述代碼發(fā)現(xiàn),15行得到a
的數(shù)據(jù)是100,仍然是定義全局變量a
時(shí)候的值,而沒有返回
testB
函數(shù)內(nèi)部的200。綜上:testB
函數(shù)內(nèi)部的a = 200
是定義了一個(gè)局部變量。
(1)global關(guān)鍵字
思考:如何在函數(shù)體內(nèi)部修改全局變量?
a = 100 def testA(): print(a) def testB(): # 想要修改全局變量a的值是200 # global 關(guān)鍵字聲明a是全局變量 global a a = 200 print(a) testA() # 100 testB() # 200 print(f'全局變量a = {a}') # 全局變量a = 200
global
關(guān)鍵字的作用是,在函數(shù)內(nèi)部聲明一個(gè)變量為全局變量。換句話說如果希望在函數(shù)內(nèi)部修改全局變量,則需要使用global
關(guān)鍵字來聲明變量。
(2)總結(jié)
如果在函數(shù)里面直接把變量a=200賦值,此時(shí)的a
不是全局變量的修改,而是相當(dāng)于在函數(shù)內(nèi)部聲明了一個(gè)新的局部變量。函數(shù)體內(nèi)部修改全局變量: 先global
聲明a
為全局變量,然后再變量重新賦值。
4、變量的查找
當(dāng)我們使用變量時(shí),會(huì)優(yōu)先在當(dāng)前作用域中尋找該變量,如果有則使用,
如果沒有則繼續(xù)去上一級(jí)作用域中尋找,如果有則使用,
如果依然沒有則繼續(xù)去上一級(jí)作用域中尋找,以此類推。
直到找到全局作用域,依然沒有找到,則會(huì)拋出異常 NameError: name 'a' is not defined
。
# 練習(xí)說明 a = 10 def fn2(): def fn3(): a = 30 print('fn3中:','a =',a) fn3() print('fn2中:','a =',a) fn2() """ 輸出結(jié)果: fn3中: a = 30 fn2中: a = 10 """
5、作用域中可變數(shù)據(jù)類型變量
c = 10 def fn4(a): # 在函數(shù)中對(duì)形參進(jìn)行重新賦值,不會(huì)影響其他的變量 a = 20 print('a =', a, id(a)) fn4(c) print('c =', c, id(c)) """ 輸出結(jié)果: a = 20 8791349231264 c = 10 8791349230944 """ # 如果形參接收到的數(shù)據(jù)是一個(gè)全局列表 # 當(dāng)在函數(shù)內(nèi)嘗試修改列表中的元素時(shí),全局列表的數(shù)據(jù)也會(huì)發(fā)生改變 c = [1,2,3] def fn4(a): # 如果形參執(zhí)行的是一個(gè)對(duì)象,當(dāng)我們通過形參去修改對(duì)象時(shí) # 會(huì)影響到所有指向該對(duì)象的變量 a[0] = 100 print('a =', a, id(a)) fn4(c) print('c =', c, id(c)) """ 輸出結(jié)果: a = [100, 2, 3] 5132808 c = [100, 2, 3] 5132808 """ # 如果我們不向全局變量有所改動(dòng) # 就需要使用我們之前學(xué)過的淺復(fù)制, # 或者傳入一個(gè)切片,就可以解決 c = [1, 2, 3] def fn4(a): # 在函數(shù)中對(duì)形參進(jìn)行重新賦值,不會(huì)影響其他的變量 a[0] = 100 print('a =', a, id(a)) fn4(c.copy()) # fn4(c[:]) print('c =', c, id(c)) """ 輸出結(jié)果: a = [100, 2, 3] 6050824 c = [1, 2, 3] 6050312 """
6、多函數(shù)程序執(zhí)行流程
一般在實(shí)際開發(fā)過程中,一個(gè)程序往往由多個(gè)函數(shù)組成,并且多個(gè)函數(shù)共享某些數(shù)據(jù),如下所示:
(1)共用全局變量
# 1. 定義全局變量 glo_num = 0 def test1(): global glo_num # 修改全局變量 glo_num = 100 def test2(): # 調(diào)用test1函數(shù)中修改后的全局變量 print(glo_num) # 2. 調(diào)用test1函數(shù),執(zhí)行函數(shù)內(nèi)部代碼:聲明和修改全局變量 test1() # 3. 調(diào)用test2函數(shù),執(zhí)行函數(shù)內(nèi)部代碼:打印 test2() # 100
(2)返回值作為參數(shù)傳遞
# 先得到函數(shù)一的返回值,再把這個(gè)返回值傳入到函數(shù)二 def test1(): return 50 def test2(num): print(num) # 1. 保存函數(shù)test1的返回值 result = test1() # 2.將函數(shù)返回值所在變量作為參數(shù)傳遞到test2函數(shù) test2(result) # 50
總結(jié)
到此這篇關(guān)于Python中變量的作用域詳解的文章就介紹到這了,更多相關(guān)Python變量的作用域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python隨機(jī)讀取文件實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了Python隨機(jī)讀取文件的相關(guān)資料,需要的朋友可以參考下2017-05-05python使用matplotlib畫柱狀圖、散點(diǎn)圖
這篇文章主要為大家詳細(xì)介紹了python使用matplotlib畫柱狀圖、散點(diǎn)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03opencv-python+yolov3實(shí)現(xiàn)目標(biāo)檢測
因?yàn)樽罱娜蝿?wù)有用到目標(biāo)檢測,快速地了解了目標(biāo)檢測這一任務(wù),并且實(shí)現(xiàn)了使用opencv進(jìn)行目標(biāo)檢測。感興趣的可以了解一下2021-06-06PyQt5使用QTimer實(shí)現(xiàn)電子時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了PyQt5使用QTimer實(shí)現(xiàn)電子時(shí)鐘,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-0716個(gè)python常用魔法函數(shù)小結(jié)
本文主要介紹了16個(gè)python常用魔法函數(shù)小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05手把手教你配置JupyterLab 環(huán)境的實(shí)現(xiàn)
這篇文章主要介紹了手把手教你配置JupyterLab 環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02Python descriptor(描述符)的實(shí)現(xiàn)
這篇文章主要介紹了Python descriptor(描述符)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11實(shí)例詳解python函數(shù)的對(duì)象、函數(shù)嵌套、名稱空間和作用域
這篇文章主要介紹了python函數(shù)的對(duì)象、函數(shù)嵌套、名稱空間和作用域 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05