【Python成長之路】python 基礎篇 -- global/nonlocal關鍵字使用

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比較有實際用途,而且使用簡單,建議掌握。

(如果有什麼建議和訴求,可以通過下面的留言區反饋,知無不言,一起學習!)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章