python3 作用域
作用域就是一個(gè) python 程序可以直接訪問(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è)特定的變量名稱。python的作用域一共有4種,分別是:
作用域的種類
- l(local):最內(nèi)層,包含局部變量,比如一個(gè)函數(shù)/方法內(nèi)部。
- e(enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個(gè)嵌套函數(shù),一個(gè)函數(shù)(或類) a 里面又包含了一個(gè)函數(shù) b ,那么對(duì)于 b 中的名稱來(lái)說(shuō) a 中的作用域就為 nonlocal。
- g(global):當(dāng)前腳本的最外層,比如當(dāng)前模塊的全局變量。
- b(built-in): 包含了內(nèi)建的變量/關(guān)鍵字等。,最后被搜索
規(guī)則順序: l –> e –> g –>gt; b。
在局部找不到,便會(huì)去局部外的局部找(例如閉包),再找不到就會(huì)去全局找,再者去內(nèi)置中找。
g_count = 0 # 全局作用域 def outer(): o_count = 1 # 閉包函數(shù)外的函數(shù)中 def inner(): i_count = 2 # 局部作用域
內(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),類(class)以及函數(shù)(def、lambda)才會(huì)引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會(huì)引入新的作用域的,也就是說(shuō)這些語(yǔ)句內(nèi)定義的變量,外部也可以訪問(wèn),如下代碼:
>>> if true: ... msg = 'i am from yapf' ... >>> msg 'i am from yapf' >>>
范例中 msg 變量定義在 if 語(yǔ)句塊中,但外部還是可以訪問(wèn)的。
如果將 msg 定義在函數(shù)中,則它就是局部變量,外部不能訪問(wèn):
>>> def test(): ... msg_inner = 'i am from yapf' ... >>> msg_inner traceback (most recent call last): file "", line 1, in nameerror: name 'msg_inner' is not defined >>>
從報(bào)錯(cuò)的信息上看,說(shuō)明了 msg_inner 未定義,無(wú)法使用,因?yàn)樗蔷植孔兞?,只有在函?shù)內(nèi)可以使用。
全局變量和局部變量
定義在函數(shù)內(nèi)部的變量擁有一個(gè)局部作用域,定義在函數(shù)外的擁有全局作用域。
局部變量只能在其被聲明的函數(shù)內(nèi)部訪問(wèn),而全局變量可以在整個(gè)程序范圍內(nèi)訪問(wèn)。調(diào)用函數(shù)時(shí),所有在函數(shù)內(nèi)聲明的變量名稱都將被加入到作用域中。如下范例: