1、課程起源
有一次在工作中編寫python工具時,遇到一個 問題:從配置文件讀取變量A後,無法在內存中把A的值改變成新的內容。爲了解決“更新內存中變量”的這個問題,查找了一些帖子,結果發現了有個很簡單的方便 -- 使用global關鍵字!
2、global關鍵字
官方對global關鍵字的作用說明如下:
global關鍵字用來在函數或其他局部作用域中使用全局變量。
不好理解沒事,先上傳一段簡單的代碼:
x = 1
def func():
print(x)
func()
結果是:1
雖然func函數裏並沒有傳入x的值,但是在函數內打印變量x時,是按照函數內的局部變量 -> 全局變量。由於func()中沒有局部變量x,因此就讀取了全局變量的x=1。因此最後 打印的結果是1
那麼如果我加上局部變量x =2 ,那結果如下:
x = 1
def func():
x =2
print(x)
func()
print(x)
結果是:
2
1
函數內如果如何對x進行操作變化,都無法改變函數外的x值。這也就是我工作中遇到的問題簡化版。
爲了解決這個問題,我們 需要學習下global關鍵字。
x = 1
def func():
global x
x =2
print(x)
func()
print(x)
結果是:
2
2
只需要在func()加上global x聲明,就可以把局部變量x=2變成全局變量,即改變了x在內存中的值。對應上述示例代碼,第一個2是func內部打印的,第2個2是func外部打印的。
因此,簡單來說 ,global關鍵字定義的變量,無論在哪裏變化,都可以直接改變內存中的值。
3、nonlocal關鍵字
其實一開始我並不知道有nonlocal這個關鍵字,但是許多大神的帖子都提到了這個函數,那我當然學習下!官方對 nonlocal作用的定義如下:
nonlocal聲明的變量不是局部變量,也不是全局變量,而是外部嵌套函數內的變量。
先來一段示例代碼:
x = 1
def func():
nonlocal x
x =2
print(x)
func()
print(x)
結果代碼報錯,SyntaxError: no binding for nonlocal 'x' found
爲什麼我只是把global換 成了nonlocal,卻報錯了?因爲nonlocal是用於函數中的函數。
x = 1
def func():
x = 2
def subfunc():
nonlocal x
x = x + 1
print('subfunc內打印的值:%d' % x)
return x
print('func內打印的值:%d' % x)
return subfunc
func()
print('func外打印的值:%d' % x)
結果是:
func內打印的值:2
func外打印的值:1
nonlocal關鍵字既沒有改變全局變量x=1的值,也沒有改變局部變量x=2的值。這就是指nonlocal聲明的變量不是局部變量,也不是全局變量。
示例代碼在func()里加了一個子函數subfunc(),但是從結果來看,似乎並沒有執行subfunc()。這是爲什麼呢?因爲我們只調用了func(),如果要調用subfunc()的話,要func()()。
x = 1
def func():
x = 2
def subfunc():
nonlocal x
x = x + 1
print('subfunc內打印的值:%d' % x)
return x
print('func內打印的值:%d' % x)
return subfunc
def func2():
# 爲了方便使用func()(),用變量F表示func()
F = func()
print('func2內第一次打印:%d' % F())
print('func2內第二次打印:%d' % F())
func2()
結果是:
func內打印的值:2
subfunc內打印的值:3
func2內第一次打印:3
subfunc內打印的值:4
func2內第二次打印:4
從這段代碼可以看到,subfunc()裏的x變量從原來的2變成了3,所以nonlocal是改變了subfunc()子函數內的變量值,即外部嵌套函數內的變量。
因此,簡單地理解,被nonlocal定義後的變量,只會在被調用的子函數中起作用。
4、課堂總結
個人理解來看,global比較有實際用途,而且使用簡單,建議掌握。
(如果有什麼建議和訴求,可以通過下面的留言區反饋,知無不言,一起學習!)