Python變數作用域



在Python中,變數的作用域定義為使用者可以訪問該變數的特定區域或範圍。變數的作用域取決於其定義的位置和方式。在Python中,變數可以具有全域性作用域或區域性作用域。

Python變數的作用域型別

根據作用域,Python變數分為三類:

  • 區域性變數

  • 全域性變數

  • 非區域性變數

區域性變數

區域性變數在特定的函式或程式碼塊內定義。只有定義它的函式或程式碼塊才能訪問它,它的作用域有限。換句話說,區域性變數的作用域僅限於其定義的函式,嘗試在其外部訪問它將導致錯誤。始終記住,多個區域性變數可以具有相同的名稱。

示例

以下示例顯示了局部變數的作用域。

def myfunction():
   a = 10
   b = 20
   print("variable a:", a)
   print("variable b:", b)
   return a+b
   
print (myfunction())

在上面的程式碼中,我們透過其函式訪問了區域性變數。因此,程式碼將產生以下輸出:

variable a: 10
variable b: 20
30

全域性變數

全域性變數可以從程式的任何部分訪問,它在任何函式或程式碼塊之外定義。它不特定於任何塊或函式。

示例

以下示例顯示了全域性變數的作用域。我們可以在函式作用域內和函式作用域外訪問它們。

#global variables
name = 'TutorialsPoint'
marks = 50
def myfunction():
   # accessing inside the function
   print("name:", name)
   print("marks:", marks)
# function call   
myfunction()

上面的程式碼將產生以下輸出:

name: TutorialsPoint
marks: 50

非區域性變數

在Python中,那些既不在區域性作用域也不在全域性作用域中定義的變數稱為非區域性變數。它們用於巢狀函式。

示例

以下示例演示了非區域性變數的工作方式。

def yourfunction():
   a = 5
   b = 6 
   # nested function
   def myfunction():
      # nonlocal function 
      nonlocal a
      nonlocal b
      a = 10
      b = 20 
      print("variable a:", a)
      print("variable b:", b)
      return a+b
   print (myfunction())
yourfunction()

上面的程式碼將產生以下輸出:

variable a: 10
variable b: 20
30

Python變數的名稱空間和作用域

名稱空間是識別符號(例如變數名、函式名、類名等)的集合。在Python中,名稱空間用於管理變數的作用域並防止命名衝突。

Python提供以下型別的名稱空間:

  • 內建名稱空間包含內建函式和內建異常。它們在載入Python直譯器時立即載入到記憶體中,並在直譯器執行期間一直存在。

  • 全域性名稱空間包含在主程式中定義的任何名稱。這些名稱在程式執行期間一直存在於記憶體中。

  • 區域性名稱空間包含在函式內部定義的名稱。它們在函式執行期間可用。

這些名稱空間是巢狀的。下圖顯示了名稱空間之間的關係。

Types Of Namespace

某個變數的生命週期僅限於其定義所在的名稱空間。因此,無法從任何外部名稱空間訪問內部名稱空間中的變數。

Python globals() 函式

Python 的標準庫包含一個內建函式 globals()。它返回當前在全域性名稱空間中可用的符號的字典。

直接從 Python 提示符執行 globals() 函式。

>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}

可以看出,包含所有內建函式和內建異常定義的內建模組已載入。

示例

儲存以下包含少量變數和一個在其內部包含更多變數的函式的程式碼。

name = 'TutorialsPoint'
marks = 50
result = True
def myfunction():
   a = 10
   b = 20
   return a+b
   
print (globals())

從這個指令碼內部呼叫 globals() 返回以下字典物件:

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000263E7255250>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\user\\examples\\main.py', '__cached__': None, 'name': 'TutorialsPoint', 'marks': 50, 'result': True, 'myfunction': <function myfunction at 0x00000263E72004A0>}

全域性名稱空間現在包含程式中的變數及其值以及其中的函式物件(而不是函式中的變數)。

Python locals() 函式

Python 的標準庫包含一個內建函式 locals()。它返回函式區域性名稱空間中當前可用符號的字典。

示例

修改上述指令碼,以從函式內部列印全域性和區域性名稱空間的字典。

name = 'TutorialsPoint'
marks = 50
result = True
def myfunction():
   a = 10
   b = 20
   c = a+b
   print ("globals():", globals())
   print ("locals():", locals())
   return c
myfunction()

輸出顯示 locals() 返回一個字典,其中包含函式中當前可用的變數及其值。

globals(): {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000169AE265250>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\mlath\\examples\\main.py', '__cached__': None, 'name': 'TutorialsPoint', 'marks': 50, 'result': True, 'myfunction': <function myfunction at 0x00000169AE2104A0>}
locals(): {'a': 10, 'b': 20, 'c': 30}

由於 globals() 和 locals() 函式都返回字典,因此可以使用字典的 get() 方法或索引運算子訪問相應名稱空間中變數的值。

print (globals()['name']) # displays TutorialsPoint
print (locals().get('a')) # displays 10

Python 中的名稱空間衝突

如果全域性和區域性作用域中都存在同名變數,Python 直譯器會優先考慮區域性名稱空間中的變數。

示例

在下面的示例中,我們定義了一個區域性變數和一個全域性變數。

marks = 50 # this is a global variable
def myfunction():
   marks = 70 # this is a local variable
   print (marks)
   
myfunction()
print (marks) # prints global value

它將產生以下輸出:

70
50

示例

如果嘗試從函式內部操作全域性變數的值,Python 會引發UnboundLocalError,如下面的示例所示:

# this is a global variable
marks = 50 
def myfunction():
   marks = marks + 20
   print (marks)

myfunction()
# prints global value
print (marks) 

它將產生以下錯誤訊息:

   marks = marks + 20
           ^^^^^
UnboundLocalError: cannot access local variable 'marks' where it is not associated with a value

示例

要修改全域性變數,可以使用字典語法更新它,或者在修改之前使用global關鍵字引用它。

var1 = 50 # this is a global variable
var2 = 60 # this is a global variable
def myfunction():
   "Change values of global variables"
   globals()['var1'] = globals()['var1']+10
   global var2
   var2 = var2 + 20

myfunction()
print ("var1:",var1, "var2:",var2) #shows global variables with changed values

執行程式碼後,它將產生以下輸出:

var1: 60 var2: 80

示例

最後,如果嘗試在全域性作用域中訪問區域性變數,Python 會引發 NameError,因為區域性作用域中的變數無法在其外部訪問。

var1 = 50 # this is a global variable
var2 = 60 # this is a global variable
def myfunction(x, y):
   total = x+y
   print ("Total is a local variable: ", total)

myfunction(var1, var2)
print (total) # This gives NameError

它將產生以下錯誤訊息:

Total is a local variable: 110
Traceback (most recent call last):
   File "C:\Users\user\examples\main.py", line 9, in <module>
   print (total) # This gives NameError
          ^^^^^
NameError: name 'total' is not defined
廣告