在Python中,我們可能在不同區(qū)域定義了相同名稱(如函數(shù)名稱、變量名稱等)的對象,那么,在Python中按照什么規(guī)則來訪問這些變量呢?本文將對這一問題進(jìn)行詳細(xì)的探討。
在Python中,名稱空間可以分為4種類型:
(1)局部名稱空間(Local Namespace): 在Python中,位于函數(shù)內(nèi)部、for循環(huán)、try-except塊是常見的局部名稱空間的例子。當(dāng)函數(shù)或?qū)?yīng)的代碼塊執(zhí)行完畢時,局部名稱空間中的對象將被刪除。
(2)包裹的名稱空間(Enclosed Namespace): 當(dāng)一個函數(shù)定義在另外一個函數(shù)內(nèi)部時,前者就定義了一個包裹的名稱空間,其生命周期與局部名稱空間相同。
(3)全局名稱空間(Global Namespace): 該類型屬于Python程序級或模塊級。模塊級的全局名稱空間當(dāng)其被調(diào)用時被創(chuàng)建。通常,模塊級的名稱空間一直保持到解釋器退出。
(4)內(nèi)建的名稱空間(Built-in Namespace): 內(nèi)建名稱空間是在Python解釋器啟動時創(chuàng)建,且不會被刪除。
Python變量按照以下規(guī)則搜索各個名稱空間。
局部(Local) -> 包裹(Enclosed) -> 全局(Global) -> 內(nèi)建(Built-in)
這通常被稱為變量作用域的LEGB規(guī)則。
即Python在使用一個變量時,如輸出,先從局部名稱空間搜索該變量,如局部沒有則進(jìn)一步搜索包裹名稱空間,如變量不存在則進(jìn)一步搜索全局名稱空間,直至內(nèi)建的名稱空間。如以上區(qū)域都無法獲取到訪問的變量,則會給出名稱未定義的錯誤。其過程可以使用下圖來表示:
下面程序特意定義了幾個層次的變量,來觀察變量的使用情況。
a = 1
b = 2
c = 3
def fun_outer():
a = 10
b = 20
def fun_inner():
a = 100
b = 200
c = 300
print(f'inner:a={a},b={b},c={c}')
fun_inner()
print(f'outer:a={a},b={b},c={c}')
fun_outer()
print(f'global:a={a},b={b},c={c}')
輸出結(jié)果如下:
inner:a=100,b=200,c=300
輸出情況,讀者可以根據(jù)程序的提示自行分析。
outer:a=10,b=20,c=3
global:a=1,b=2,c=3
由模塊導(dǎo)入的變量需要通過模塊名稱來引用。
import math
import numpy
pi = 3.14
print(f'pi = {pi}')
print(f'pi = {math.pi}')
print(f'pi = {numpy.pi}')
輸出結(jié)果如下:
pi = 3.14
pi = 3.141592653589793
pi = 3.141592653589793
理解Python名稱空間及作用域非常有必要,以免在實(shí)際使用中產(chǎn)生意想不到的問題。最好的做法是盡量使用不同的名稱來定義自己需要的對象,以避免混淆,造成程序運(yùn)行結(jié)果達(dá)不到預(yù)期結(jié)果。
本文(完)
新聞熱點(diǎn)
疑難解答