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