在被呼叫函式內賦值的變元和變數,處於該函式的“區域性作用域”。在所有函式之外賦值的變數,屬於“全域性作用域”。處於區域性作用域的變數,被稱為“區域性變數”。處於全域性作用域的變數,被稱為“全域性變數”。一個變數必是其中一種,不能既是區域性的又是全域性的。
可以將“作用域”看成是變數的容器。當作用域被銷燬時,所有儲存在該作用域內的變數的值就被丟棄了。只有一個全域性作用域,它是在程式開始時建立的。如果程式終止,全域性作用域就被銷燬,它的所有變數就被丟棄了。否則,下次你執行程式的時候,這些變數就會記住它們上次執行時的值。一個函式被呼叫時,就建立了一個區域性作用域。在這個函式內賦值的所有變數,存在於該區域性作用域內。該函式返回時,這個區域性作用域就被銷燬了,這些變數就丟失了。下次呼叫這個函式,區域性變數不會記得該函式上次被呼叫時它們儲存的值。
作用域很重要,理由如下:

  • 全域性作用域中的程式碼不能使用任何區域性變數;
  • 但是,區域性作用域可以訪問全域性變數;
  • 一個函式的區域性作用域中的程式碼,不能使用其他區域性作用域中的變數。
  • 如果在不同的作用域中,你可以用相同的名字命名不同的變數。也就是說,可以有一個名為spam 的區域性變數,和一個名為spam 的全域性變數。(不建議)

全域性變數不能引用區域性作用域的變數。

import sys, random
def spam():
    egg = 123
spam()
print(egg)
'''egg是spam函式的區域性變數,呼叫完後就銷燬了。所以會報錯。
Traceback (most recent call last):
  File "py\dz.py", line 25, in <module>
    print(egg)
NameError: name 'egg' is not defined'''

區域性作用域不能使用其他區域性作用域的區域性變數。

def spam():
    egg = 99
    bacon()
    print(egg)

def bacon():
    ham = 101
    egg = 0

spam()
#輸出99

全域性變數可以在區域性作用域中讀取。

def spam():
    print(egg)
egg = 42    #全域性變數
spam()
print(egg)
#輸出42 42

使用global語句讓區域性作用域對全域性變數進行寫的操作。
(不用global而直接在區域性作用域對全域性變數進行寫的操作會報錯)

def spam():
    global egg
    egg = 'spam'
egg = 'global'
spam()
print(egg)    #輸出spam

完畢!