Python中變量的作用域及global用法


Python 中,一個變量的作用域總是由在代碼中被賦值的地方所決定的。

1、函數定義了本地作用域,而模塊定義的是全局作用域。如果想要在函數內定義全局作用域,需要加上global修飾符。

2、變量名解析:LEGB原則

當在函數中使用未認證的變量名時,Python搜索4個作用域:

①本地作用域(L)(函數內部聲明但沒有使用global的變量)

②之后是上一層結構中def或者lambda的本地作用域(E)

③之后是全局作用域(G)(函數中使用global聲明的變量或在模塊層聲明的變量)

④最后是內置作用域(B)(即python的內置類和函數等)

如果在第一處能夠找到這個變量名,那么python此時會停止查找。如果變量名在整個的搜索過程中都沒有找到,Python就會報錯。

補充:上面的變量規則只適用於簡單對象,當出現引用對象的屬性時,則有另一套搜索規則:屬性引用搜索一個或多個對象,而不是作用域,並且有可能涉及到所謂的"繼承"

3、global修飾符的用法:

①首先是python的一個奇異現象,在模塊層面定義的變量(無需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,得到了我們想要的效果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM