這篇文章主要講解了“Python中變量作用域是什么意思”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python中變量作用域是什么意思”吧!
我們經常聽說Python函數訪問局部變量、全局變量;在定義裝飾器的時候,還會使用自由變量。這些不同的變量是如何賦值、初始化、查找及修改的呢?各自的作用細則又是什么樣的呢?本篇嘗試解答這個問題。
Python中的變量名可以指代變量、函數、類、對象等。一般來說,每個對象都有一個變量名指向,更準確說是 綁定。
為啥變量要有作用域呢?
我們在Python里遇到的內置、局部、全局及自由變量,就是說變量的作用域。
語言區分作用域,是為了復用變量名。引入作用域,相當于給變量劃分了各自的“隔離區”,在不同”隔離區“里,查找變量變得很容易。
正是因為有了作用域,我們在函數內才可以隨意使用變量名,而不擔心其與全局變量、其他函數中的變量沖突——因為這兩個作用域是分割的。
BASIC語言只有全局變量,你能想象嗎?你在一個函數里命名的循環變量i,很可能跟全局變量沖突。寫起程序來,舉步維艱。且會導致很多修改、檢索問題,維護很困難。
Python 有哪些作用域呢?
Python是動態類型語言,變量是在定義的時候賦值的。這句話的意思我們分以下幾個方面來理解:
a = 1 賦值時定義變量
from tools import cubie 導入時定義變量 cubie
def fun():pass 定義函數,綁定變量fun
def fun(name=None):pass 定義變量name為函數fun的形式變量(也是局部變量),同時定義函數,綁定便令fun
class Car:pass 定義類,綁定類名Car
以上,我們弄清了變量定義的時刻,下面來看變量的作用域,也就是變量的活動空間怎么規定出來的。
變量作用域取決于其 定義位置。
定義在函數內部的變量、定義在函數聲明中的形式參數,視為局部變量。
定義在 .py 文件內的,且函數、類之外的變量,視為全局變量。
定義在函數中,嵌套函數外,且被嵌套函數引用的變量,視為自由變量。
定義在builtin中的變量,視為內置變量。
面對如此復雜的四種變量作用域,用一個例子來說明它們的訪問規則。
四個作用域遵循LEGB規則,讓我們用一個例子來說明。
import builtins builtins.b = 'builtins' g = 'global' def outer(o1,o2='o2'): e = 'enclose' def inner(i1,i2='i2'): print(i1,i2,o1,o2,e,g,b) return inner fun = outer('o1') fun('i1')
其輸出為 i1 i2 o1 o2 enclose global builtins
可見,在outer函數的嵌套函數inner中的輸出語句 print(i1,i2,o1,o2,e,g,b) 是本程序的重點。其具體執行情況如下:
print i1和i2,毫無疑問的局部變量。
print o1和o2,本地作用域沒有,向上查找到outer函數形參。形參也為局部變量,所以該變量實際定義在outer函數內,inner這個內嵌函數外,而inner內部引用了這個變量,所以視為自由變量。
print e,本地作用域沒有,類似上例,視為自由變量。
print g,本地作用域沒有,自由變量作用域(閉包)沒有,一直上溯到全局作用局找到。
print b,本地作用域沒有,自由變量作用域(閉包)沒有,全局作用局沒有,一致上溯到內置變量空間找到。
至此,LEGB規則呼之欲出:在本地空間尋找不到的變量,逐級向上級尋找。這里的LEGB分別指代Local,Enclose,Global和Builtin。
在函數中讀取和賦值全局變量,在內嵌函數中讀取和賦值自由變量,會有一些不同的地方。
對變量名的賦值和引用,是兩種不同的情況:
賦值:創建一個變量或者修改。
引用:檢索其值。
以上兩者的差別,會導致我們在函數中:
賦值一個
鴻蒙官方戰略合作共建——HarmonyOS技術社區
全局變量:等于創建一個局部變量。
自由變量:等于創建一個局部變量。
引用:正常檢索其值。
我們修改上例中的inner函數為如下形式:
def inner(i1,i2='i2'): e = 'enclose' g = 'inner global' print(i1,i2,o1,o2,e,g,b)
在嵌套函數內,重新定義了g變量,其他語言一般理解這是重新賦值全局變量。但是我們看上條規則:在函數中,賦值一個全局變量時,等于創建一個局部變量。就是說此時的g已經是局部變量了——在程序最后的 print(g) 語句輸出 global,而不是修改后的 inner global 也驗證了以上規則。
完整代碼如下:
import builtins builtins.b = 'builtins' g = 'global' def outer(o1,o2='o2'): e = 'enclose' g = 'inner global' def inner(i1,i2='i2'): print(i1,i2,o1,o2,e,g,b) return inner fun = outer('o1') fun('i1') print(g)
輸出結果如下:
i1 i2 o1 o2 enclose inner global builtins global
不重新賦值,只是使用全局變量和自由變量,則沒有問題。
自由變量也是類似的情況。
為了解決局部作用域中賦值全局變量和自由變量導致的變成局部變量問題,Python引入關鍵字 global 和 nonlocal 。
def inner(i1,i2='i2'): global g nonlocal e g = 'inner global' e = 'inner enclose'
此時的賦值,則分別是對全局變量和自由變量的操作,而非新建局部變量。
完整代碼如下:
import builtins builtins.b = 'builtins' g = 'global' def outer(o1,o2='o2'): e = 'enclose' def inner(i1,i2='i2'): global g nonlocal e g = 'inner global' e = 'inner enclose' print(i1,i2,o1,o2,e,g,b) return inner fun = outer('o1') fun('i1') print(g)
輸出結果如下:
i1 i2 o1 o2 inner enclose inner global builtins inner global
Python的作用域分為四種,分別是局部、全局、自由和內置;
定義變量的位置決定了變量的作用域;
作用域的查找遵守LEGB規則;
為了在局部作用域中修改全局變量和自由變量,引入了 global 關鍵字和 nonlocal 關鍵字。
感謝各位的閱讀,以上就是“Python中變量作用域是什么意思”的內容了,經過本文的學習后,相信大家對Python中變量作用域是什么意思這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。