Python中局部變量和全局變量舉例詳解
引入例子拆解
源碼
class A: def __init__(self): self.test = 0 def add(c, k): c.test = c.test + 1 k = k + 1 def main(): Count = A() k = 0 for i in range(0, 25): add(Count, k) print("Count.test=", Count.test) print("k=", k) main()
運(yùn)行結(jié)果如下圖
代碼解析
這段代碼定義了一個(gè)類(lèi)A
和一個(gè)函數(shù)add
,然后在main
函數(shù)中創(chuàng)建了類(lèi)A
的一個(gè)實(shí)例,并使用了一個(gè)局部變量k
。
1.類(lèi)定義:
class A: def __init__(self): self.test = 0
這里定義了一個(gè)名為A
的類(lèi),它有一個(gè)特殊的方法__init__
,這是一個(gè)構(gòu)造函數(shù),當(dāng)創(chuàng)建類(lèi)A
的新實(shí)例時(shí)會(huì)被自動(dòng)調(diào)用。在這個(gè)方法中,初始化實(shí)例變量self.test
并將其設(shè)置為0。
2.函數(shù)定義:
def add(c, k): c.test = c.test + 1 k = k + 1
這里定義了一個(gè)名為add
的函數(shù),它接受兩個(gè)參數(shù)c
和k
。函數(shù)內(nèi)部,它將參數(shù)c
的test
屬性增加1,并將參數(shù)k
的值增加1。
3.主函數(shù):
def main(): Count = A() k = 0 for i in range(0, 25): add(Count, k) print("Count.test=", Count.test) print("k=", k)
main
函數(shù)是程序的入口點(diǎn)。首先,它創(chuàng)建了類(lèi)A
的一個(gè)實(shí)例,并將其賦值給變量Count
。然后,它初始化一個(gè)局部變量k
并將其設(shè)置為0。
接下來(lái),main
函數(shù)使用一個(gè)for
循環(huán),循環(huán)25次,每次調(diào)用add
函數(shù),并將Count
實(shí)例和k
變量作為參數(shù)傳遞。
在循環(huán)結(jié)束后,main
函數(shù)打印出Count.test
和k
的值。
4.調(diào)用主函數(shù):
main()
最后,調(diào)用main
函數(shù)來(lái)執(zhí)行程序。
輸出結(jié)果:
Count.test
的值將會(huì)是25,因?yàn)樵诿看握{(diào)用add
函數(shù)時(shí),Count
實(shí)例的test
屬性都會(huì)增加1。k
的值將會(huì)是0,因?yàn)樵?code>add函數(shù)中對(duì)k
的修改并不會(huì)影響main
函數(shù)中的k
變量。在add
函數(shù)中,k
被重新綁定為一個(gè)新的局部變量,它只是臨時(shí)地覆蓋了傳入的k
值,但這個(gè)修改只在add
函數(shù)的局部作用域內(nèi)有效。一旦add
函數(shù)執(zhí)行結(jié)束,這個(gè)局部變量k
就會(huì)被銷(xiāo)毀,而main
函數(shù)中的k
變量保持不變。
因此,最終的輸出為:
Count.test= 25 k= 0
Python3命名空間和作用域
命名空間
命名空間(Namespace)是從名稱(chēng)到對(duì)象的映射,大部分的命名空間都是通過(guò) Python 字典來(lái)實(shí)現(xiàn)的。每個(gè)命名空間都有一個(gè)與之關(guān)聯(lián)的作用域。
命名空間提供了在項(xiàng)目中避免名字沖突的一種方法。各個(gè)命名空間是獨(dú)立的,沒(méi)有任何關(guān)系的,所以一個(gè)命名空間中不能有重名,但不同的命名空間是可以重名而沒(méi)有任何影響。
如下一個(gè)計(jì)算機(jī)系統(tǒng)中的例子,一個(gè)文件夾(目錄)中可以包含多個(gè)文件夾,每個(gè)文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
一般有三種命名空間:
- 內(nèi)置名稱(chēng)(built-in names), Python 語(yǔ)言內(nèi)置的名稱(chēng),比如函數(shù)名 abs、char 和異常名稱(chēng) BaseException、Exception 等等。
- 全局名稱(chēng)(global names),模塊中定義的名稱(chēng),記錄了模塊的變量,包括函數(shù)、類(lèi)、其它導(dǎo)入的模塊、模塊級(jí)的變量和常量。包含模塊中的所有全局變量和函數(shù)。
- 局部名稱(chēng)(local names),函數(shù)中定義的名稱(chēng),記錄了函數(shù)的變量,包括函數(shù)的參數(shù)和局部定義的變量。(類(lèi)中定義的也是),只在這個(gè)函數(shù)或類(lèi)中有效。
命名空間查找順序
假設(shè)我們要使用變量 runoob,則 Python 的查找順序?yàn)椋?strong>局部的命名空間 -> 全局命名空間 -> 內(nèi)置命名空間。
如果找不到變量 runoob,它將放棄查找并引發(fā)一個(gè) NameError 異常:
NameError: name 'runoob' is not defined。
命名空間的生命周期
命名空間的生命周期取決于對(duì)象的作用域,如果對(duì)象執(zhí)行完成,則該命名空間的生命周期就結(jié)束。
因此,我們無(wú)法從外部命名空間訪問(wèn)內(nèi)部命名空間的對(duì)象。
# var1 是全局名稱(chēng) var1 = 3 def some_func(): # var2 是局部名稱(chēng) var2 = 6 def some_inner_func(): # var3 是內(nèi)嵌的局部名稱(chēng) var3 = 8
相同的對(duì)象名稱(chēng)可以存在于多個(gè)命名空間中,如下圖。
作用域
作用域就是一個(gè) Python 程序可以直接訪問(wèn)命名空間的正文區(qū)域,即變量可以被訪問(wèn)的區(qū)域。
在一個(gè) python 程序中,直接訪問(wèn)一個(gè)變量,會(huì)從內(nèi)到外依次訪問(wèn)所有的作用域直到找到,否則會(huì)報(bào)未定義的錯(cuò)誤。
Python 中,程序的變量并不是在哪個(gè)位置都可以訪問(wèn)的,訪問(wèn)權(quán)限決定于這個(gè)變量是在哪里賦值的。
變量的作用域決定了在哪一部分程序可以訪問(wèn)哪個(gè)特定的變量名稱(chēng)。Python 的作用域一共有4種,分別是:
有四種作用域:
- L(Local):最內(nèi)層,包含局部變量,比如一個(gè)函數(shù)/方法內(nèi)部。這是最內(nèi)層的作用域,通常指的是函數(shù)內(nèi)部的作用域。在這個(gè)作用域內(nèi)聲明的變量,只能在該函數(shù)內(nèi)部被訪問(wèn)和修改。
- E(Enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個(gè)嵌套函數(shù),一個(gè)函數(shù)(或類(lèi)) A 里面又包含了一個(gè)函數(shù) B ,那么對(duì)于 B 中的名稱(chēng)來(lái)說(shuō) A 中的作用域就為 nonlocal。當(dāng)函數(shù)定義在另一個(gè)函數(shù)內(nèi)部時(shí),內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)的局部變量,即允許嵌套函數(shù)訪問(wèn)外層函數(shù)的局部變量。這里的外部函數(shù)的作用域就被稱(chēng)為封閉作用域。封閉作用域中的變量可以被內(nèi)部函數(shù)訪問(wèn),但內(nèi)部函數(shù)不能直接修改外部函數(shù)的局部變量,除非使用
nonlocal
聲明。 - G(Global):當(dāng)前腳本的最外層,比如當(dāng)前模塊的全局變量。這是模塊級(jí)別的命名空間,包含了模塊中定義的所有全局變量和函數(shù)。全局變量可以在模塊內(nèi)的任何位置被訪問(wèn)和修改,除非它們被局部作用域中的同名變量遮蔽。
- B(Built-in): 包含了內(nèi)建的變量/關(guān)鍵字等,最后被搜索。這是最外層的作用域,包含了Python解釋器提供的內(nèi)置函數(shù)和變量,如
len()
,print()
,True
,False
等,可以被任何模塊訪問(wèn)。
規(guī)則順序: L –> E –> G –> B。
在局部找不到,便會(huì)去局部外的局部找(例如閉包),再找不到就會(huì)去全局找,再者去內(nèi)置中找。
如果在查找過(guò)程中找到了變量,就不會(huì)再繼續(xù)向上查找。如果在當(dāng)前作用域中找到了同名的變量,那么這個(gè)變量會(huì)遮蔽外層作用域中的同名變量。例如,如果在局部作用域中聲明了一個(gè)變量,那么它就會(huì)遮蔽全局作用域中的同名變量。
g_count = 3 # 全局作用域 def outer(): o_count = 4 # 閉包函數(shù)外的函數(shù)中 def inner(): i_count = 5 # 局部作用域
內(nèi)置作用域是通過(guò)一個(gè)名為 builtin 的標(biāo)準(zhǔn)模塊來(lái)實(shí)現(xiàn)的,但是這個(gè)變量名自身并沒(méi)有放入內(nèi)置作用域內(nèi),所以必須導(dǎo)入這個(gè)文件才能夠使用它。在Python3.0中,可以使用以下的代碼來(lái)查看到底預(yù)定義了哪些變量:
import builtins dir(builtins)
Python 中只有模塊(module),類(lèi)(class)以及函數(shù)(def、lambda)才會(huì)引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會(huì)引入新的作用域的,也就是說(shuō)這些語(yǔ)句內(nèi)定義的變量,外部也可以訪問(wèn),如下代碼:
實(shí)例中name變量定義在if語(yǔ)句塊中,但外部還是可以訪問(wèn)的。
如果將name定義在函數(shù)中,則它就是局部變量,外部無(wú)法訪問(wèn):
從報(bào)錯(cuò)的信息上看,說(shuō)明了 name_inner 未定義,無(wú)法使用,因?yàn)樗蔷植孔兞浚挥性诤瘮?shù)內(nèi)可以使用。
在 Python 中,return 語(yǔ)句用于從函數(shù)中返回一個(gè)值。當(dāng)函數(shù)調(diào)用一個(gè) return 語(yǔ)句時(shí),函數(shù)的執(zhí)行將停止,并將一個(gè)值返回給函數(shù)調(diào)用者。在函數(shù)中使用 return 語(yǔ)句可以返回任何類(lèi)型的數(shù)據(jù),包括數(shù)字,字符串,列表,元組和字典等。
使用 return 語(yǔ)句時(shí),我們可以選擇是否返回值。如果函數(shù)沒(méi)有 return 語(yǔ)句,函數(shù)將返回 None 值。None 表示空值,意味著它沒(méi)有值,與 0,'' 或空列表不同。
全局變量和局部變量
定義在函數(shù)內(nèi)部的變量擁有一個(gè)局部作用域,定義在函數(shù)外的擁有全局作用域。
局部變量只能在其被聲明的函數(shù)內(nèi)部訪問(wèn),而全局變量可以在整個(gè)程序范圍內(nèi)訪問(wèn)。調(diào)用函數(shù)時(shí),所有在函數(shù)內(nèi)聲明的變量名稱(chēng)都將被加入到作用域中。
讓我們通過(guò)幾個(gè)關(guān)鍵點(diǎn)來(lái)清晰明了地理解局部變量和全局變量的區(qū)別:
定義位置
- 局部變量:在函數(shù)內(nèi)部定義的變量。
- 全局變量:在所有函數(shù)外部定義的變量,通常是在模塊級(jí)別。
作用域
- 局部變量:僅在定義它們的函數(shù)內(nèi)部可見(jiàn)。
- 全局變量:在整個(gè)程序中可見(jiàn),包括所有函數(shù)內(nèi)部。
生命周期
- 局部變量:當(dāng)函數(shù)被調(diào)用時(shí)創(chuàng)建,當(dāng)函數(shù)執(zhí)行結(jié)束時(shí)銷(xiāo)毀。
- 全局變量:程序運(yùn)行期間一直存在,直到程序結(jié)束。
修改規(guī)則
- 局部變量:在函數(shù)內(nèi)部對(duì)局部變量的修改只影響該函數(shù)內(nèi)部的變量。
- 全局變量:在函數(shù)內(nèi)部對(duì)全局變量的修改會(huì)影響全局變量的值,但需要使用
global
關(guān)鍵字來(lái)聲明。
如下實(shí)例:
x = 10 # 全局變量 def my_function(): print("Inside function, x =", x) # 訪問(wèn)全局變量x y = 20 # 局部變量 print("Inside function, y =", y) my_function() print("Outside function, x =", x) # 訪問(wèn)全局變量x # print("Outside function, y =", y) # 這將引發(fā)錯(cuò)誤,因?yàn)閥是局部變量
在這個(gè)例子中,x是全局變量,可以在函數(shù)內(nèi)部和外部訪問(wèn)。而y是局部變量,只能在my_function函數(shù)內(nèi)部訪問(wèn)。
如果我們嘗試在函數(shù)外部訪問(wèn)y,將會(huì)引發(fā)一個(gè)NameError,因?yàn)閥的作用域僅限于my_function函數(shù)內(nèi)部。
global 和 nonlocal關(guān)鍵字
當(dāng)內(nèi)部作用域想修改外部作用域的變量時(shí),就要用到global和nonlocal關(guān)鍵詞了。
例:
修改全局變量
如果想在函數(shù)內(nèi)部修改全局變量,需要使用global關(guān)鍵字:
x = 10 # 全局變量 def my_function(): global x # 聲明x是全局變量 print("Inside function, x =", x) x = 20 # 修改全局變量x print("Inside function, x =", x) my_function() print("Outside function, x =", x) # x的值也被修改了
在這個(gè)例子中,通過(guò)使用global關(guān)鍵字,my_function函數(shù)內(nèi)部的修改影響了全局變量x
的值。
最佳實(shí)踐
- 使用局部變量:盡量使用局部變量,因?yàn)樗鼈兊淖饔糜蛴邢?,有助于避免命名沖突和意外的修改。
- 謹(jǐn)慎使用全局變量:全局變量可能會(huì)導(dǎo)致代碼難以理解和維護(hù),因?yàn)樗鼈兛梢栽诔绦虻娜魏蔚胤奖恍薷?。如果確實(shí)需要使用全局變量,確保它們的使用是必要的,并且明確地使用
global
關(guān)鍵字聲明。
修改封閉作用域中的變量
如果要修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量則需要nonlocal關(guān)鍵字了。nonlocal關(guān)鍵字在Python中用于在嵌套的函數(shù)作用域中修改變量。當(dāng)你有一個(gè)嵌套函數(shù),并且想要在內(nèi)部函數(shù)中修改外部函數(shù)的變量時(shí),可以使用nonlocal關(guān)鍵字。這與global關(guān)鍵字的作用類(lèi)似,但nonlocal用于封閉作用域中的變量,而不是全局作用域。
nonlocal關(guān)鍵字通常用在閉包(closure)中,即一個(gè)函數(shù)內(nèi)定義了另一個(gè)函數(shù),內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)的變量。
def outer(): x = 10 # 外部函數(shù)的局部變量 def inner(): nonlocal x # 聲明x是封閉作用域中的變量 print("Inside inner, x =", x) x = 20 # 修改外部函數(shù)的局部變量x print("Inside inner, x =", x) inner() print("Outside inner, x =", x) outer()
在這個(gè)例子中:
- outer函數(shù)定義了一個(gè)局部變量
x
。 - innner函數(shù)是嵌套在outer函數(shù)內(nèi)部的。
- 在inner函數(shù)中,使用nonlocal x聲明x是封閉作用域中的變量,即outer函數(shù)的局部變量。
- 在inner函數(shù)中修改x的值,這個(gè)修改會(huì)影響到outer函數(shù)中的x。
與global的區(qū)別
- global:用于修改全局作用域中的變量。
- nonlocal:用于修改封閉作用域中的變量,通常是嵌套函數(shù)中的外部函數(shù)的局部變量。
注意事項(xiàng)
- 使用nonlocal時(shí),變量必須在封閉作用域中定義,否則會(huì)引發(fā)UnboundLocalError。
- nonlocal關(guān)鍵字不能用于類(lèi)定義中。
最佳實(shí)踐
- 在使用嵌套函數(shù)時(shí),如果需要在內(nèi)部函數(shù)中修改外部函數(shù)的變量,使用nonlocal關(guān)鍵字。
- 避免過(guò)度使用nonlocal,因?yàn)樗赡軙?huì)使代碼的可讀性和可維護(hù)性降低。盡量通過(guò)參數(shù)傳遞和返回值來(lái)實(shí)現(xiàn)函數(shù)之間的數(shù)據(jù)交換。
特殊情況
另外有一種特殊情況,假設(shè)下面這段代碼被運(yùn)行:
a = 10 def test(): a = a + 1 print(a) test()
錯(cuò)誤信息為局部作用域引用錯(cuò)誤,因?yàn)?test 函數(shù)中的 a 使用的是局部,未定義,無(wú)法修改。
修改 a 為全局變量:
a = 10 def test(): global a a = a + 1 print(a) test()
也可以通過(guò)函數(shù)參數(shù)傳遞:
a = 10 def test(a): a = a + 1 print(a) test(a)
輸出結(jié)果均為:11。如下圖:
內(nèi)置函數(shù):locals和globals
這兩個(gè)函數(shù)主要提供,基于字典的訪問(wèn)局部和全局變量的方式。locals()和globals()是兩個(gè)內(nèi)置函數(shù),分別用于訪問(wèn)當(dāng)前局部和全局符號(hào)表。這些符號(hào)表實(shí)際上是字典,其中包含了當(dāng)前作用域中的變量名和它們的值。
在理解這兩個(gè)函數(shù)時(shí),首先來(lái)理解一下 Python 中的名字空間概念。Python 使用叫做名字空間的東西來(lái)記錄變量的軌跡。名字空間只是一個(gè)字典,它的鍵字就是變量名,字典的值就是那些變量的值。
實(shí)際上,名字空間可以像 Python 的字典一樣進(jìn)行訪問(wèn)。
每個(gè)函數(shù)都有著自已的名字空間,叫做局部名字空間,它記錄了函數(shù)的變量,包括函數(shù)的參數(shù)和局部定義的變量。每個(gè)模塊擁有它自已的名字空間,叫做全局名字空間,它記錄了模塊的變量,包括函數(shù)、類(lèi)、其它導(dǎo)入的模塊、模塊級(jí)的變量和常量。還有就是內(nèi)置名字空間,任何模塊均可訪問(wèn)它,它存放著內(nèi)置的函數(shù)和異常。
當(dāng)一行代碼要使用變量 x 的值時(shí),Python 會(huì)到所有可用的名字空間去查找變量,按照如下順序:
- 1、局部名字空間 - 特指當(dāng)前函數(shù)或類(lèi)的方法。如果函數(shù)定義了一個(gè)局部變量 x,Python將使用這個(gè)變量,然后停止搜索。
- 2、全局名字空間 - 特指當(dāng)前的模塊。如果模塊定義了一個(gè)名為 x 的變量,函數(shù)或類(lèi),Python將使用這個(gè)變量然后停止搜索。
- 3、內(nèi)置名字空間 - 對(duì)每個(gè)模塊都是全局的。作為最后的嘗試,Python 將假設(shè) x 是內(nèi)置函數(shù)或變量。
如果 Python 在這些名字空間找不到 x,它將放棄查找并引發(fā)一個(gè) NameError 的異常,同時(shí)傳遞 There is no variable named 'x' 這樣一條信息。
局部變量函數(shù) locals 例子(locals 返回一個(gè)名字/值對(duì)的字典):
lobals()
- locals()函數(shù)返回一個(gè)代表當(dāng)前局部符號(hào)表的字典。
- 這個(gè)字典包含了當(dāng)前作用域中定義的所有變量,包括函數(shù)參數(shù)和局部變量。
def my_function(): local_var = 20 print(locals()) my_function()
輸出將類(lèi)似于:
{ 'local_var': 20, '__module__': '__main__', '__annotations__': {}, '__doc__': None, ... }
locals()返回的字典包含了在函數(shù)my_function中定義的所有局部變量。
def foo(arg, a): x = 1 y = 'xxxxxx' for i in range(10): j = 1 k = i print(locals()) #調(diào)用函數(shù)的打印結(jié)果 foo(1,2)
這段代碼定義了一個(gè)名為 foo的函數(shù),它接受兩個(gè)參數(shù) arg和 a。在函數(shù)內(nèi)部,定義了兩個(gè)局部變量 x和 y,并初始化了它們的值。然后,函數(shù)進(jìn)入一個(gè) for 循環(huán),循環(huán)10次,每次循環(huán)中定義了兩個(gè)變量 j 和 k,并分別將 j 初始化為1,將 k 設(shè)置為當(dāng)前循環(huán)的索引 i。
在循環(huán)結(jié)束后,函數(shù)打印出當(dāng)前的局部變量字典 locals()。這個(gè)字典包含了函數(shù)內(nèi)所有局部變量的名稱(chēng)和值。
為什么結(jié)果是 `{'arg': 1, 'a': 2, 'x': 1, 'y': 'xxxxxx', 'i': 9, 'j': 1, 'k': 9}` 呢?讓我們逐步分析:
arg 和 a 是函數(shù)的參數(shù),分別被賦值為1和2。
x 和 y 是在函數(shù)體中定義的局部變量,分別被賦值為1和字符串 'xxxxxx'。
在 for 循環(huán)中,i 從0開(kāi)始,每次循環(huán)遞增1,直到9。在循環(huán)的最后一次,i 的值是9。
j 在每次循環(huán)的開(kāi)始被重新賦值為1,因此不管循環(huán)多少次,j 的值總是1。
k 在每次循環(huán)中被賦值為當(dāng)前的 i 值,因此在最后一次循環(huán)中,k 的值也是9。
由于 locals() 返回的是函數(shù)執(zhí)行到當(dāng)前點(diǎn)的所有局部變量的快照,所以在 for 循環(huán)結(jié)束后,locals() 包含了所有這些變量及其最終的值。這就是為什么看到的結(jié)果是包含所有這些變量及其值的字典。
from module import 和 import module 之間的不同。使用 import module,模塊自身被導(dǎo)入,但是它保持著自己的名字空間,這就是為什么需要使用模塊名來(lái)訪問(wèn)它的函數(shù)或?qū)傩裕╩odule.function)的原因。但是使用 from module import,實(shí)際上是從另一個(gè)模塊中將指定的函數(shù)和屬性導(dǎo)入到你自己的名字空間,這就是為什么你可以直接訪問(wèn)它們卻不需要引用它們所來(lái)源的模塊的原因。
globals()
- globals()函數(shù)返回一個(gè)代表當(dāng)前全局符號(hào)表的字典。
- 這個(gè)字典包含了在模塊頂級(jí)作用域中定義的所有變量,包括函數(shù)、類(lèi)、導(dǎo)入的模塊和變量等。
# 定義一些全局變量 global_var1 = 10 global_var2 = "Hello" # 打印全局變量字典 print(globals())
輸出將類(lèi)似于:
{ '__name__': '__main__', 'global_var1': 10, 'global_var2': 'Hello', ... }
globals()返回的字典包含了當(dāng)前模塊的所有全局變量。注意,輸出的具體內(nèi)容可能會(huì)根據(jù)你定義的其他全局變量而有所不同。
與globals()的區(qū)別
locals 是只讀的,globals 不是。
locals 不可修改,globals 可以修改,原因是:
- locals() 實(shí)際上沒(méi)有返回局部名字空間,它返回的是一個(gè)拷貝。所以對(duì)它進(jìn)行修改,修改的是拷貝,而對(duì)實(shí)際的局部名字空間中的變量值并無(wú)影響。
- globals() 返回的是實(shí)際的全局名字空間,而不是一個(gè)拷貝與 locals 的行為完全相反。
所以對(duì) globals 所返回的 dictionary 的任何的改動(dòng)都會(huì)直接影響到全局變量的取值。
z = 6 #定義全局變量 def foo(arg): x = 1 print( locals() ) print('x=',x) locals()['x'] = 2 #修改的是局部名字空間的拷貝,而實(shí)際的局部名字空間中的變量值并無(wú)影響。 print( locals() ) print( "x=",x ) foo(3) print( globals() ) print( 'z=',z ) globals()["z"] = 8 #globals()返回的是實(shí)際的全局名字空間,修改變量z的值 print( globals() ) print( "z=",z )
輸出將類(lèi)似于:
{'arg': 3, 'x': 1} x= 1 {'arg': 3, 'x': 1} x= 1 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b099358>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test.py', '__cached__': None, 'z': 6, 'foo': <function foo at 0x10ae48e18>} z= 6 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10b099358>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test.py', '__cached__': None, 'z': 8, 'foo': <function foo at 0x10ae48e18>} z= 8
注意事項(xiàng)
- 使用locals()和globals()時(shí)要小心,因?yàn)椴划?dāng)使用可能會(huì)導(dǎo)致代碼難以理解和維護(hù)。
- 在嵌套函數(shù)中使用locals()時(shí),它返回的是當(dāng)前函數(shù)的局部變量,而不是外部函數(shù)的局部變量。
- 修改locals()或globals()字典中的值會(huì)直接影響作用域中的變量,但通常不推薦這樣做,因?yàn)樗赡軙?huì)導(dǎo)致代碼難以追蹤和理解。
總結(jié)
到此這篇關(guān)于Python中局部變量和全局變量的文章就介紹到這了,更多相關(guān)Python局部變量和全局變量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 異常的傳遞性及主動(dòng)拋出學(xué)習(xí)
這篇文章主要為大家介紹了python 異常的傳遞性及主動(dòng)拋出學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03python實(shí)現(xiàn)折半查找和歸并排序算法
這篇文章主要介紹了python實(shí)現(xiàn)折半查找和歸并排序算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Python使用matplotlib繪圖無(wú)法顯示中文問(wèn)題的解決方法
這篇文章主要介紹了Python使用matplotlib繪圖無(wú)法顯示中文問(wèn)題的解決方法,結(jié)合具體實(shí)例形式分析了Python使用matplotlib繪圖時(shí)出現(xiàn)中文亂碼的原因與相關(guān)解決方法,需要的朋友可以參考下2018-03-03Python判斷字符串是否xx開(kāi)始或結(jié)尾的示例
今天小編就為大家分享一篇Python判斷字符串是否xx開(kāi)始或結(jié)尾的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08Python使用plt.boxplot()函數(shù)繪制箱圖、常用方法以及含義詳解
箱線圖一般用來(lái)展現(xiàn)數(shù)據(jù)的分布,如上下四分位值、中位數(shù)等,也可以直觀地展示異常點(diǎn),下面這篇文章主要給大家介紹了關(guān)于Python使用plt.boxplot()函數(shù)繪制箱圖、常用方法以及含義詳解的相關(guān)資料,需要的朋友可以參考下2022-08-08Python中創(chuàng)建包和增添包的路徑(sys.path.append())
本文主要介紹了Python中創(chuàng)建包和增添包的路徑(sys.path.append()),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01