1. 程式人生 > >python中作用域以及global關鍵字的用法

python中作用域以及global關鍵字的用法

一、Python 中的作用域:

       一個變數的作用域是由在程式碼中被賦值的地方所決定的。

  • 函式定義了本地作用域,而模組定義的是全域性作用域。
    如果想要在函式內定義全域性作用域,需要加上global修飾符。
  • 變數名解析:LEGB原則
       當在函式中使用未認證的變數名時,Python搜尋4個作用域[本地作用域(L)(函式內部宣告但沒有使用global的變數),之後是上一層結構中def或者lambda的本地作用域(E),之後是全域性作用域(G)(函式中使用global宣告的變數或在模組層宣告的變數),最後是內建作用域(B)(即python的內建類和函式等)]並且在第一處能夠找到這個變數名的地方停下來。如果變數名在整個的搜尋過程中都沒有找到,Python就會報錯。
    補:上面的變數規則只適用於簡單物件,當出現引用物件的屬性時,則有另一套搜尋規則:屬性引用搜索一個或多個物件,而不是作用域,並且有可能涉及到所謂的"繼承"
  • 以上基於http://blog.csdn.net/carolzhang8406/article/details/6855525
二、global關鍵字的用法:
  • 首先是pythond的一個奇異現象,在模組層面定義的變數(無需global修飾),如果在函式中沒有再定義同名變數,可以在函式中當做全域性變數使用:hehe=6
def f():
    print(hehe)
f()
print(hehe)
上述程式碼可以正常執行且輸出為6和6
  • 但如果在函式中有再賦值/定義(因為python是弱型別語言,賦值語句和其定義變數的語句一樣),則會產生引用了未定義變數的錯誤:
hehe=6
def f():
    print(hehe)
    hehe=2
f()
print(hehe)
       丟擲的錯誤資訊為:UnboundLocalError: local variable 'hehe' referenced before assignment
  • 而如果在函式中的定義在引用前使用,那麼會正常執行但函式中的變數和模組中定義的全域性變數不為同一個
hehe=6
def f():
    hehe=2
    print(hehe)
f()
print(hehe) 
上述輸出是2和6,也即f函式中print使用的是區域性變數hehe,而最後一個print語句使用的全域性hehe
  • 那麼我們會有疑問,如果我可能在函式使用某一變數後又對其進行修改(也即再賦值),怎麼讓函式裡面使用的變數是模組層定義的那個全域性變數而不是函式內部的區域性變數呢?這時候global修飾符就派上用場了。
hehe=6
def f():
    global hehe
    print(hehe)
    hehe=3
f()
print(hehe) 
  • 在用global修飾符宣告hehe是全域性變數的hehe後(注意,global語句不允許同時進行賦值如global hehe=3是不允許的),上述輸出是6和3,得到了我們想要的效果。