6.3. 命名空間及範圍 (namespace and scope)
接下來要介紹變數的命名空間(namespace)及範圍(scope),在Python中一個變數名稱可以參考(或指向)到不同的東西,這取決於在什麼地方使用到變數名稱。
每一個函數都會定義自己的命名空間,在這個名命空間中的變數名稱都是獨一無二的,如果在另一個命名空間也有相同的變數名稱,這兩者的變數名稱雖然相同,然而參考的東西是原全不同的。例如:在一個命名空間中有一個變數名稱 x,並且在另一個命名空間中也有一個變名稱x,雖然這兩個變數的名稱相同,但是它們所參考到的東西(或值)是不同的。
所以,根據一個程式中由於命名間的不同,使得變數的作用範圍也不同,可以分成下列兩種範圍:
- 全域範圍(global scope)
- 區域範圍(local scope)
進而使用變數可以分成下列兩種變數:
- 全域變數(global variables)
- 區域變數(local variables)
因此,我們可以從上述得知,一個函數中的變數名稱是位於該函數的命名空間,即區域範圍,而這些變數就是區域變數。如果,變數名稱不是位於區域範圍,則是屬於整個程式的命名空間,即全域範圍,同時也是全域變數。需要注意的是,在全域範圍中不能使用區域變數,但是在區域範圍內可以使用全域變數。此外,在不同區域範圍內的區域變數也不能互相使用。
使用 globals() 及 locals() 取得命名空間的內容
如果想要知道一個程式或函數的命名間時,可以使用 globals() 及 locals() 變取得命名空間的內容。
- 參考檔案:namespace_scope.py
- 或參考下列範例:
>>> a = 1
>>> b = 2.0
>>>
>>> def local_function():
... a = 3
... c = '4'
... d = 5.0
...
... print('-Local variables', locals())
...
>>>
>>> print('Global varialbes', globals())
Global varialbes {'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'a': 1,
'b': 2.0,
'local_function': <function local_function at 0x00000000003F3E18>}
>>>
>>> local_function()
-Local variables {'d': 5.0, 'c': '4', 'a': 3}
>>>
在函數中存取全域變數
在一個函數中可以使用(或讀取)全域變數。
#定義全域變數
a = 1
# 定義函數
def print_global_variable():
print('-inside functon, global variable:', a, id(a))
# 主要程式碼
# 呼叫函數
print('outside function, global variable:', a, id(a))
print_global_variable()
# 執行結果
outside function, global variable: 1 140144167442176
-inside function, global variable: 1 140144167442176
但是,在一個函數中要修改全域變數時,則是會產生另一個名稱相同的區變數,而不是修改全域變數的值。
#定義全域變數
a = 1
# 定義函數
def print_global_variable():
a = 3
print('-inside functon, global variable:', a, id(a))
# 主要程式碼
# 呼叫函數
print('before function, global variable:', a, id(a))
print_global_variable()
print('after function, global variable:', a, id(a))
# 執行結果
before function, global variable: 1 140378945931008
-inside functon, global variable: 3 140378945931072
after function, global variable: 1 140378945931008
所以,要在一個函數中修改全域變數的值,需要使用 global 關鍵字來指定要存取那一個全域變數。若在函數中有修改該全域變數,則全域變數會指向新的記憶體位址。
global 變數名稱
#定義全域變數
a = 1
# 定義函數
def print_global_variable():
# 使用global關鍵字
global a
a = 3
print('-inside functon, global variable:', a, id(a))
# 主要程式碼
# 呼叫函數
print('before function, global variable:', a, id(a))
print_global_variable()
print('after function, global variable:', a, id(a))
# 執行結果
before function, global variable: 1 140590434682624
-inside functon, global variable: 3 140590434682688
after function, global variable: 3 140590434682688
參考資料
- Python自動化的樂趣, 第三章, Al Sweigart 著、H&C 譯, 碁峰
- Python編程入門第3版(簡), 第五章, Toby Donaldson著, 人民郵電出版社
- 精通Python, 第四章, Bill Lubanovic著, 賴屹民譯, 歐萊禮