您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么理解python全局變量,局部變量和命名空間”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Python 使用全局和局部變量的方式是特立獨行的。雖然在許多或大多數其他編程語言中,如果未另行聲明,變量將被視為全局變量,而 Python 則以相反的方式處理變量。如果沒有另外聲明,它們是本地的。這種方法背后的驅動原因是全局變量通常是不好的做法,應該避免。在大多數情況下,您想使用全局變量,最好使用參數將值放入函數或返回值以將其取出。與許多其他程序結構一樣,Python 也通過設計強加了良好的編程習慣。
因此,當您在函數定義中定義變量時,默認情況下它們是該函數的局部變量。也就是說,您對函數體中的此類變量所做的任何操作都不會影響函數外的其他變量,即使它們具有相同的名稱。換句話說,函數體是這樣一個變量的范圍,即這個名稱與其值相關聯的封閉上下文。
所有變量都有塊的作用域,它們在那里被聲明和定義。它們只能在聲明點之后使用。
簡單說一下:變量不必也不能以在 Java 或 C 等編程語言中聲明的方式聲明。Python 中的變量通過定義它們來隱式聲明,即第一次分配值到一個變量,這個變量被聲明并自動具有必須分配給它的對象的數據類型。
在下面的示例中,我們想演示如何在函數體內使用全局值:
def f (): print ( s ) s = “我愛夏天的巴黎!” f ()
輸出:
我愛夏天的巴黎!
在調用函數 f() 之前,變量 s 被定義為字符串“我愛夏天的巴黎!”。f() 的主體僅由“print(s)”語句組成。由于沒有局部變量 s,即沒有賦值給 s,將使用全局變量 s 的值。所以輸出將是字符串“我愛夏天的巴黎!”。問題是,如果我們在函數 f() 中改變 s 的值會發生什么?它也會影響全局變量嗎?我們在下面的一段代碼中對此進行了測試:
def f (): s = "我愛倫敦!" 打印( s ) s = “我愛巴黎!” f () 打印( s )
輸出:
我愛倫敦!
我愛巴黎!
如果我們將第一個示例與第二個示例結合起來,即我們首先使用 print() 函數訪問 s,希望獲得全局值,然后為其分配一個新值呢?給它賦值,意味著 - 正如我們之前所說的 - 創建一個局部變量 s。因此,我們會將 s 作為同一范圍內的全局變量和局部變量,即函數體。幸運的是,Python 不允許這種歧義。因此,它會引發錯誤,正如我們在以下示例中所見:
def f (): print ( s ) s = “我愛倫敦!” 打印( s ) s = “我愛巴黎!” f ()
輸出:
UnboundLocalError Traceback (最近一次調用最后一次)
<ipython-input-3-d7a23bc83c27> in <module>
5
6 s = “我愛巴黎!”
----> 7 f ( )
<ipython-input-3-d7a23bc83c27> in f ()
1 def f ( ) :
----> 2 print ( s )
3 s = “我
愛倫敦!” 4 打印( s )
5
UnboundLocalError:賦值前引用了局部變量“s”
變量不能在函數內既是局部的又是全局的。由于在 f() 內部為 s 賦值,因此 Python 決定我們需要一個局部變量,因此在 s 定義之前的第一個打印語句拋出了上面的錯誤信息。任何在函數內部更改或創建的變量都是局部變量,如果它沒有被聲明為全局變量。要告訴 Python,我們要使用全局變量,我們必須使用關鍵字“global”明確說明這一點,如下例所示:
def f (): global s print ( s ) s = "只在春天,但倫敦也很棒!" 打印( s ) s = "我在巴黎找課程!" f () 打印( s )
輸出:
我正在巴黎尋找課程!
只在春天,但倫敦也很棒!
只在春天,但倫敦也很棒!
函數調用完成后,不能從外部訪問函數的局部變量。這是上一個例子的延續:
def f (): s = "我在全球范圍內不為人知" 打印( s ) f () 打印( s )
輸出:
我在全球不為人知
只在春天,但倫敦也很棒!
以下示例顯示了局部和全局變量以及函數參數的狂野組合:
def foo ( x , y ): 全局 a a = 42 x , y = y , x b = 33 b = 17 c = 100 打印( a , b , x , y ) a , b , x , y = 1 , 15 , 3 , 4 foo ( 17 , 4 ) 打印( a , b , x , y )
輸出:
42 17 4 17
42 15 3 4
如果我們在嵌套函數中使用 global 關鍵字,我們現在將檢查會發生什么。以下示例顯示了在各種范圍內使用變量“city”的情況:
def f (): city = "Hamburg" def g (): global city city = "Geneva" print ( "調用前g:" + city ) print ( "現在調用g:" ) g () print ( "調用后g: " + 城市) f () print ( "主城的值:" + city )
輸出:
之前打電話給g:漢堡
現在調用 g:
打電話后g:漢堡
主要城市價值:日內瓦
我們可以看到嵌套函數 g 中的 global 語句不會影響函數 f 的變量“city”,即它保持其值“Hamburg”。我們還可以從這個例子中推斷出,在調用 f() 之后,模塊命名空間中存在一個變量 'city',其值為 'Geneva'。這意味著嵌套函數中的 global 關鍵字不會影響其封閉命名空間的命名空間!這與我們在前一章中發現的一致:在函數內部定義的變量是局部變量,除非它明確標記為全局變量。換句話說,我們可以在任何封閉作用域中引用一個變量名,但我們只能在局部作用域中通過賦值重新綁定變量名,或者通過使用全局聲明在模塊全局作用域中重新綁定變量名。我們還需要一種方法來訪問其他作用域的變量。這樣做的方法是非局部定義,我們將在下一章解釋。
Python3 引入了非局部變量作為一種新的變量。非局部變量與全局變量有很多共同點。與全局變量的一個區別在于,無法通過使用非局部語句來更改模塊范圍內的變量,即未在函數內部定義的變量。我們在以下兩個示例中展示了這一點:
def f (): 全球 城市 打印( city ) city = "法蘭克福" f ()
輸出:
法蘭克福
該程序是正確的,并返回“Frankfurt”作為輸出。我們將在以下程序中將“全局”更改為“非本地”:
def f (): 非本地 城市 打印( city ) city = "法蘭克福" f ()
輸出:
文件“<ipython-input-9-97bb311dfb80>” ,第2
行 非本地城市
^
語法錯誤:未找到非本地“城市”的綁定
這表明非局部綁定只能在嵌套函數內部使用。必須在封閉的函數作用域中定義非局部變量。如果變量未在封閉函數作用域中定義,則變量不能在嵌套作用域中定義。這是與“全局”語義的另一個區別。
def f (): city = "Munich" def g (): nonlocal city city = "Zurich" print ( "調用前g:" + city ) print ( "現在調用g:" ) g () print ( "調用后g: " + 城市) city = "Stuttgart" f () print ( "'city' in main:" + city )
輸出:
打電話之前 g: 慕尼黑
現在調用 g:
撥打 g 后:蘇黎世
主要的“城市”:斯圖加特
在前面的例子中,變量 'city' 是在調用 g 之前定義的。如果沒有定義,我們會得到一個錯誤:
高清 ?F (): #city = “慕尼黑” 高清 g ^ (): 外地 市 城市 = “蘇黎世” 打印(“呼叫摹前:” + 城市) 打印(“立即致電G:” ) g ^ () 打印(“后呼叫 g: " + city ) city = "Stuttgart" f () print ( "'city' in main:" + city )
輸出:
文件“<ipython-input-11-5417be93b6a6>” ,第4
行 非本地城市
^
語法錯誤:未找到非本地“城市”的綁定
該程序運行良好 - 如果我們將“非本地”更改為“全局”,在 f - 內有或沒有 'city = "Munich"' 行:
def f (): #city = "Munich" def g (): global city city = "Zurich" print ( "Before call g:" + city ) print ( "Calling g now:" ) g () print ( "After 調用g:" )呼叫 g: " + city ) city = "Stuttgart" f () print ( "'city' in main:" + city )
輸出:
打電話之前:斯圖加特
現在調用 g:
撥打 g 后:蘇黎世
主要的“城市”:蘇黎世
然而有一個巨大的不同:全局 x 的值現在發生了變化!
“怎么理解python全局變量,局部變量和命名空間”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。