程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

您不知道的Python中global、nonlocal哪些事兒

編輯:Python

Python中全局變量、局部變量以及global、nonlocal關鍵字的用法

1.全局變量和局部變量

前言:

  • 全局變量是在整個py文件中聲明,全局范圍內都可以訪問;
  • 局部變量是在某個函數中聲明的,只能在該函數中調用它,如果試圖在超出范圍的地方調用,程序就爆掉了
  • 如果在函數內部定義與某個全局變量一樣名稱的局部變量,就可能會導致意外的效果,可能不是你期望的。因此不建議這樣使用,這樣會使得程序很不健全。

有 4 條法則,來區分一個變量是處於局部作用域還是全局作用域:

  1. 如果變量在全局作用域中使用(即在所用函數之外),它就總是全局變量。
  2. 如果在一個函數中,有針對該變量的 global 語句,它就是全局變量。
  3. 否則,如果該變量用於函數中的賦值語句,它就是局部變量。
  4. 但是,如果該變量沒用用在賦值語句中,它就是全局變量。

閱讀 例1,可以更好地理解這些法則,

# 例 1
def test1():
global str1
str1 = 'hello' # 這是全局變量
def test2():
str1 = 'python' # 這是局部變量
def test3():
print(str1) # 這是全局變量
str1 = 42 # 這是全局變量
test1()
print(str1) # out: hello

解釋:在 test1() 函數中,str1 是全局 str1 變量,因為在函數的開始處,有針對 str1 變量的 global 語句。在 test2() 函數中,str1 是局部變量,因為在該函數中有針對它的賦值語句。在 test3() 函數中,str1 是全局變量,因為在這個函數中,既沒有賦值語句,也沒有針對它的 global 語句。

  • 在一個函數中,一個變量要麼總是局部變量,要麼總是全局變量。函數中的代碼沒有辦法先使用名為 str1 的局部變量,稍後又在同一個函數中使用全局變量。
  • 如果想在一個函數中修改全局變量中存儲的值,就必須對該變量使用 global 語句。
  • 在一個函數中,如果試圖在局部變量賦值之前就使用它,Python就會報錯。如例2
#例 2
def test1():
print(str1) # ERROR
str1 = 'hello world' # 局部變量
str1 = 'hi' # 全局變量
test1()
''' 報錯: File "E:/test/test.py", line 92, in test1 print(str1) # ERROR UnboundLocalError: local variable 'str1' referenced before assignment '''

例2解釋:之所以報錯,因為 Python 看到 test1() 函數中有針對 str1 的賦值語句,所以會認為 str1 變量是局部變量。但是 print(str1) 語句的執行在 str1 賦值之前,局部變量 str1 並不存在(即賦值之前應用本地變量 str1)。Python不會退回使用全局 str1 變量。

2. global語句

使用 global 語句可以在一個函數內修改全局變量。如果在函數內的頂部有 " global str1 "這樣的代碼,它就告訴 Python ,“在這個函數中,str1 指的是全局變量,所以不要用這個名字創建一個局部變量”。例如下面代碼:

def test1():
global str1
str1 = 'one'
str1 = 'global'
test1()
print(str1) # out: one

因為 str1 在 test1() 的頂部被聲明 gloabl,所以當 str1 被賦值為 ‘one’ 時,賦值發生在全局作用域的 str1 上。沒有創建局部 str1 變量。

3. nonlocal語句

Python 3.0 引入了一條新的nonlocal語句,實際上,當執行到 nonlocal 語句的時候,nonlocal中列出的名稱必須在一個嵌套的def中提前定義過,否則,將會產生一個錯誤。nonlocal名稱只能出現在嵌套的def中,而不能在模塊的全局作用域中或def之外的內置作用域中。
表示在局部作用域中,調用父級作用域中的變量;如果嵌套了很多層,最多只能作用到最頂層的函數,不能作用於全局變量。


動手算算這些題,理論要和實際相結合

a = 1
def func_1():
a =2
def func_2():
# a = 3 #模塊A
def func_3():
nonlocal a
a = 4
print(' 8行:',a)
print(' 9行:',a)
func_3()
print('11行:',a)#2 --> 4
print('12行:',a)
func_2()
print('14行:',a)#2-->4
print('15行:',a)
func_1()
print('17行:',a)#全局變量,nonlocal無權更改

上面代碼中,加上模塊A的結果:

不加模塊A的結果:


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved