這篇文章主要講解了“Python3命名空間和作用域是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Python3命名空間和作用域是什么”吧!
創(chuàng)新互聯(lián)一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個客戶多一個朋友!為您提供成都做網(wǎng)站、網(wǎng)站建設(shè)、成都網(wǎng)頁設(shè)計、微信小程序開發(fā)、成都網(wǎng)站開發(fā)、成都網(wǎng)站制作、成都軟件開發(fā)、手機APP定制開發(fā)是成都本地專業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計公司,等你一起來見證!命名空間
命名空間(Namespace)是從名稱到對象的映射,大部分的命名空間都是通過 Python 字典來實現(xiàn)的。
命名空間提供了在項目中避免名字沖突的一種方法。各個命名空間是獨立的,沒有任何關(guān)系的,所以一個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。
我們舉一個計算機系統(tǒng)中的例子,一個文件夾(目錄)中可以包含多個文件夾,每個文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
一般有三種命名空間:
內(nèi)置名稱(built-in names), Python 語言內(nèi)置的名稱,比如函數(shù)名 abs、char 和異常名稱 BaseException、Exception 等等。
全局名稱(global names),模塊中定義的名稱,記錄了模塊的變量,包括函數(shù)、類、其它導(dǎo)入的模塊、模塊級的變量和常量。
局部名稱(local names),函數(shù)中定義的名稱,記錄了函數(shù)的變量,包括函數(shù)的參數(shù)和局部定義的變量。(類中定義的也是)
命名空間查找順序:
假設(shè)我們要使用變量 runoob,則 Python 的查找順序為:局部的命名空間去 -> 全局命名空間 -> 內(nèi)置命名空間。
如果找不到變量 runoob,它將放棄查找并引發(fā)一個 NameError 異常:
NameError: name 'runoob' is not defined。
命名空間的生命周期:
命名空間的生命周期取決于對象的作用域,如果對象執(zhí)行完成,則該命名空間的生命周期就結(jié)束。
因此,我們無法從外部命名空間訪問內(nèi)部命名空間的對象。
實例 # var1 是全局名稱 var1 = 5 def some_func(): # var2 是局部名稱 var2 = 6 def some_inner_func(): # var3 是內(nèi)嵌的局部名稱 var3 = 7
如下圖所示,相同的對象名稱可以存在于多個命名空間中。
作用域
作用域就是一個 Python 程序可以直接訪問命名空間的正文區(qū)域。
在一個 python 程序中,直接訪問一個變量,會從內(nèi)到外依次訪問所有的作用域直到找到,否則會報未定義的錯誤。
Python 中,程序的變量并不是在哪個位置都可以訪問的,訪問權(quán)限決定于這個變量是在哪里賦值的。
變量的作用域決定了在哪一部分程序可以訪問哪個特定的變量名稱。Python的作用域一共有4種,分別是:
有四種作用域:
L(Local):最內(nèi)層,包含局部變量,比如一個函數(shù)/方法內(nèi)部。
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個嵌套函數(shù),一個函數(shù)(或類) A 里面又包含了一個函數(shù) B ,那么對于 B 中的名稱來說 A 中的作用域就為 nonlocal。
G(Global):當前
腳本的最外層,比如當前模塊的全局變量。
B(Built-in): 包含了內(nèi)建的變量/關(guān)鍵字等。,最后被搜索
規(guī)則順序: L –> E –> G –>gt; B。
在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全局找,再者去內(nèi)置中找。
g_count = 0 # 全局作用域 def outer(): o_count = 1 # 閉包函數(shù)外的函數(shù)中 def inner(): i_count = 2 # 局部作用域
內(nèi)置作用域是通過一個名為 builtin 的標準模塊來實現(xiàn)的,但是這個變量名自身并沒有放入內(nèi)置作用域內(nèi),所以必須導(dǎo)入這個文件才能夠使用它。在Python3.0中,可以使用以下的代碼來查看到底預(yù)定義了哪些變量:
>>> import builtins >>> dir(builtins)
Python 中只有模塊(module),類(class)以及函數(shù)(def、lambda)才會引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會引入新的作用域的,也就是說這些語句內(nèi)定義的變量,外部也可以訪問,如下代碼:
>>> if True: ... msg = 'I am from Runoob' ... >>> msg 'I am from Runoob' >>>
實例中 msg 變量定義在 if 語句塊中,但外部還是可以訪問的。
如果將 msg 定義在函數(shù)中,則它就是局部變量,外部不能訪問:
>>> def test(): ... msg_inner = 'I am from Runoob' ... >>> msg_inner Traceback (most recent call last): File "", line 1, inNameError: name 'msg_inner' is not defined >>>
從報錯的信息上看,說明了 msg_inner 未定義,無法使用,因為它是局部變量,只有在函數(shù)內(nèi)可以使用。
全局變量和局部變量
定義在函數(shù)內(nèi)部的變量擁有一個局部作用域,定義在函數(shù)外的擁有全局作用域。
局部變量只能在其被聲明的函數(shù)內(nèi)部訪問,而全局變量可以在整個程序范圍內(nèi)訪問。調(diào)用函數(shù)時,所有在函數(shù)內(nèi)聲明的變量名稱都將被加入到作用域中。如下實例:
實例(Python 3.0+) #!/usr/bin/python3 total = 0 # 這是一個全局變量 # 可寫函數(shù)說明 def sum( arg1, arg2 ): #返回2個參數(shù)的和." total = arg1 + arg2 # total在這里是局部變量. print ("函數(shù)內(nèi)是局部變量 : ", total) return total #調(diào)用sum函數(shù) sum( 10, 20 ) print ("函數(shù)外是全局變量 : ", total)
以上實例輸出結(jié)果:
函數(shù)內(nèi)是局部變量 : 30 函數(shù)外是全局變量 : 0
global 和 nonlocal關(guān)鍵字
當內(nèi)部作用域想修改外部作用域的變量時,就要用到global和nonlocal關(guān)鍵字了。
以下實例修改全局變量 num:
實例(Python 3.0+) #!/usr/bin/python3 num = 1 def fun1(): global num # 需要使用 global 關(guān)鍵字聲明 print(num) num = 123 print(num) fun1() print(num)
以上實例輸出結(jié)果:
1 123 123
如果要修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量則需要 nonlocal 關(guān)鍵字了,如下實例:
實例(Python 3.0+) #!/usr/bin/python3 def outer(): num = 10 def inner(): nonlocal num # nonlocal關(guān)鍵字聲明 num = 100 print(num) inner() print(num) outer()
以上實例輸出結(jié)果:
100 100
另外有一種特殊情況,假設(shè)下面這段代碼被運行:
實例(Python 3.0+) #!/usr/bin/python3 a = 10 def test(): a = a + 1 print(a) test()
以上程序執(zhí)行,報錯信息如下:
Traceback (most recent call last): File "test.py", line 7, intest() File "test.py", line 5, in test a = a + 1 UnboundLocalError: local variable 'a' referenced before assignment
錯誤信息為局部作用域引用錯誤,因為 test 函數(shù)中的 a 使用的是局部,未定義,無法修改。
修改 a 為全局變量,通過函數(shù)參數(shù)傳遞,可以正常執(zhí)行輸出結(jié)果為:
實例(Python 3.0+) #!/usr/bin/python3 a = 10 def test(a): a = a + 1 print(a) test(a)
執(zhí)行輸出結(jié)果為:
11
感謝各位的閱讀,以上就是“Python3命名空間和作用域是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Python3命名空間和作用域是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!