6.3. 命名空間及範圍 (namespace and scope)


接下來要介紹變數的命名空間(namespace)及範圍(scope),在Python中一個變數名稱可以參考(或指向)到不同的東西,這取決於在什麼地方使用到變數名稱。

每一個函數都會定義自己的命名空間,在這個名命空間中的變數名稱都是獨一無二的,如果在另一個命名空間也有相同的變數名稱,這兩者的變數名稱雖然相同,然而參考的東西是原全不同的。例如:在一個命名空間中有一個變數名稱 x,並且在另一個命名空間中也有一個變名稱x,雖然這兩個變數的名稱相同,但是它們所參考到的東西(或值)是不同的。

所以,根據一個程式中由於命名間的不同,使得變數的作用範圍也不同,可以分成下列兩種範圍:

  • 全域範圍(global scope)
  • 區域範圍(local scope)

進而使用變數可以分成下列兩種變數:

  • 全域變數(global variables)
  • 區域變數(local variables)

因此,我們可以從上述得知,一個函數中的變數名稱是位於該函數的命名空間,即區域範圍,而這些變數就是區域變數。如果,變數名稱不是位於區域範圍,則是屬於整個程式的命名空間,即全域範圍,同時也是全域變數。需要注意的是,在全域範圍中不能使用區域變數,但是在區域範圍內可以使用全域變數。此外,在不同區域範圍內的區域變數也不能互相使用。

使用 globals() 及 locals() 取得命名空間的內容

如果想要知道一個程式或函數的命名間時,可以使用 globals() 及 locals() 變取得命名空間的內容。

>>> 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著, 賴屹民譯, 歐萊禮

results matching ""

    No results matching ""