1. 程式人生 > 實用技巧 >python global 與 nonlocal

python global 與 nonlocal

global 關鍵字

定義在main函式或者外部的變數是全域性變數,我們可以訪問,但是如果需要求改則需要使用改關鍵詞.
即如果需要在區域性域修改全域性變數,則需要需要使用global關鍵字再次宣告

def scope():
    global a, t  # 否則不能修改
    a += 1
    t += 'yy'
    print(a, t, g)

if __name__ == '__main__':
    a = 0
    t = 'sss'
    g = [1, 2, 3]
    scope()
1 sssyy [1, 2, 3]

否則如下則修改失敗

a = 'init...'

def scope():
    a = 'change..'

if __name__ == '__main__':
    scope()
    print(a)
init...

nonlocal 關鍵字

簡單說,該關鍵字用在巢狀函式中,可以用來改變一個變數的作用域,即在本不是該區域性域的變數作用域的地方,繼續使用該變數
如下,如果沒有使用nonlocal 關鍵字,因為msg 是不可變型別,所以msg由原來的outisde變成inside,值變了,python就會重新開闢新記憶體,導致不能修改“原來的值outside”

def outside():
    msg = "Outside!"
    def inside():
        nonlocal msg  # 若去掉, 則修改不會成功。結果輸出“outside!”
        msg = "Inside!"
    inside()
    print(msg)
outside()
Inside!

但是該變數不能作用於全域性變數。因為也好理解,如果你要修改,則可以用global
如下,會報錯:

msg = "Outside!"

def outside():
    def inside():
        nonlocal msg
        msg = "Inside!"
    inside()
    print(msg)
outside()
 nonlocal msg
    ^
SyntaxError: no binding for nonlocal 'msg' found

補充例子:
如下,對於可變型別,在外層函式id(d)和內層函式id(d)是一致的,而修改的是d["outside"]會導致記憶體改變——d['outside']是不可變型別,如下使用id(d['outside'])檢視確實改變了,但是對於整體的id(d)是不變的,所以不需要使用nonlocal也可以修改成功

def outside():
    d = {"outside": 'init'}
    print(id(d))
    print(id(d['outside']))
    def inside():
        d["outside"] = 'change'
        print(id(d))  # 是一致的, 沒有改變
        print(id(d['outside']))  # 改變了,但是隻要id(d)未改變就能修改成功
    inside()
    print(d)
outside()
{'outside': 'change'}