溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python變量作用域有哪些

發布時間:2020-08-25 17:04:51 來源:億速云 閱讀:346 作者:Leah 欄目:編程語言

Python變量作用域有哪些?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

在程序中定義一個變量時,這個變量是有作用范圍的,變量的作用范圍被稱為它的作用域。

根據定義變量的位置,變量分為兩種:

局部變量:在函數中定義的變量,包括參數,都被稱為局部變量。

全局變量:在函數外面、全局范圍內定義的變量,被稱為全局變量。

每個函數在執行時,系統都會為該函數分配一塊“臨時內存空間”,所有的局部變量都被保存在這塊臨時內存空間內。當函數執行完成后,這塊內存空間就被釋放了,這些局部變量也就失效了,因此離開函數之后就不能再訪問局部變量了。

全局變量意味著它們可以在所有函數內被訪問。

不管是在函數的局部范圍內還是在全局范圍內,都可能存在多個變量,每個變量“持有”該變量的值。從這個角度來看,不管是局部范圍還是全局范圍,這些變量和它們的值就像一個“看不見”的字典,其中變量名就是字典的 key,變量值就是字典的 value。

實際上,Python 提供了如下三個工具函數來獲取指定范圍內的“變量字典”:

globals():該函數返回全局范圍內所有變量組成的“變量字典”。

locals():該函數返回當前局部范圍內所有變量組成的“變量字典”。

vars(object):獲取在指定對象范圍內所有變量組成的“變量字典”。如果不傳入object 參數,vars() 和 locals() 的作用完全相同。

globals() 和 locals() 看似完全不同,但它們實際上也是有聯系的,關于這兩個函數的區別和聯系大致有以下兩點:

locals() 總是獲取當前局部范圍內所有變量組成的“變量字典”,因此,如果在全局范圍內(在函數之外)調用 locals() 函數,同樣會獲取全局范圍內所有變量組成的“變量字典”;而 globals() 無論在哪里執行,總是獲取全局范圍內所有變量組成的“變量字典”。

一般來說,使用 locals() 和 globals() 獲取的“變量字典”只應該被訪問,不應該被修改。但實際上,不管是使用 globals() 還是使用 locals() 獲取的全局范圍內的“變量字典”,都可以被修改,而這種修改會真正改變全局變量本身:但通過 locals() 獲取的局部范圍內的“變量字典”,即使對它修改也不會影響局部變量。

下面程序示范了如何使用 locals()、globals() 函數訪問局部范圍和全局范圍內的“變量字典”:

def test ():
    age = 20
    # 直接訪問age局部變量
    print(age) # 輸出20
    # 訪問函數局部范圍的“變量數組”
    print(locals()) # {'age': 20}
    # 通過函數局部范圍的“變量數組”訪問age變量
    print(locals()['age']) # 20
    # 通過locals函數局部范圍的“變量數組”改變age變量的值
    locals()['age'] = 12
    # 再次訪問age變量的值
    print('xxx', age) # 依然輸出20
    # 通過globals函數修改x全局變量
    globals()['x'] = 19
x = 5
y = 20
print(globals()) # {..., 'x': 5, 'y': 20}
# 在全局訪問內使用locals函數,訪問的是全局變量的“變量數組”
print(locals()) # {..., 'x': 5, 'y': 20}
# 直接訪問x全局變量
print(x) # 5
# 通過全局變量的“變量數組”訪問x全局變量
print(globals()['x']) # 5
# 通過全局變量的“變量數組”對x全局變量賦值
globals()['x'] = 39
print(x) # 輸出39
# 在全局范圍內使用locals函數對x全局變量賦值
locals()['x'] = 99
print(x) # 輸出99

從上面程序可以清楚地看出,locals() 函數用于訪問特定范圍內的所有變量組成的“變量字典”,而 globals() 函數則用于訪問全局范圍內的全局變量組成的“變量字典”。

全局變量默認可以在所有函數內被訪問,但如果在函數中定義了與全局變量同名的變量,此時就會發生局部變量遮蔽(hide)全局變量的情形。例如如下程序:

name = 'Charlie'
def test ():
    # 直接訪問name全局變量
    print(name) # Charlie
test()
print(name)

上面程序中,第 4 行直接訪問 name 變量,這是允許的,此時程序將會輸出 Charlie。如果在此之后增加如下一行代碼:

name = '孫悟空'

再次運行該程序,將會看到如下錯誤:

UnboundLocalError : local variable ‘name’ referenced before assignment

該錯誤提示粗體字代碼所訪問的 name 變量還未定義。這是什么原因呢?這正是由于程序在 test() 函數中增加了“name='孫悟空'”一行代碼造成的。

Python 語法規定,在函數內部對不存在的變量賦值時,默認就是重新定義新的局部變量。因此這行代碼相當于重新定義了 name 局部變量,這樣 name 全局變量就被遮蔽了,所以程序會報錯。

為了避免這個問題,可以通過以下兩種方式來修改上面程序:

訪問被遮蔽的全局變量。如果希望程序依然能訪問 name 全局變量,且在函數中可重新定義 name 局部變量,也就是在函數中可以訪問被遮蔽的全局變量,此時可通過 globals() 函數來實現,將上面程序改為如下形式即可:

name = 'Charlie'
def test ():
    # 直接訪問name全局變量
    print(globals()['name'])  # Charlie
    name = '孫悟空'
test()
print(name)  # Charlie

在函數中聲明全局變量。為了避免在函數中對全局變量賦值(不是重新定義局部變量),可使用 global 語句來聲明全局變量。因此,可將程序改為如下形式:

name = 'Charlie'
def test ():
    # 聲明name是全局變量,后面的賦值語句不會重新定義局部變量
    global name
    # 直接訪問name全局變量
    print(name)  # Charlie
    name = '孫悟空'
test()
print(name)  # 孫悟空

增加了“global name”聲明之后,程序會把 name 變量當成全局變量,這意味著 test() 函數后面對 name 賦值的語句只是對全局變量賦值,而不是重新定義局部變量。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女