1. 程式人生 > >python中作用域

python中作用域

ron 技術分享 語言 ref 全局變量 模塊 lba 結構 details

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,得到了我們想要的效果。

python中作用域