Python作用域與名字空間原理詳解
Python具有靜態(tài)作用域,變量的作用域由它定義的位置決定,而與調(diào)用的位置無關(guān)。
a = 2
def f():
a = 2
第一行的a的作用域是全局作用域,作用于定義位置后面的所有位置。
第四行的a的作用域是局部作用域,作用于f函數(shù)里。
Python能夠形成局部作用域的只有函數(shù)與類,其他語句不形成局部作用域。
函數(shù)與類的局部作用域
def f(): a = 1 class A: b = 2 if 1 == 1: c = 3 for _ in range(1): d = 4 while True: e = 5 break print(c, d, e) try: print(a) except Exception as e: print(e) try: print(b) except Exception as e: print(e)
輸出結(jié)果
3 4 5
name 'a' is not defined
name 'b' is not defined
python動態(tài)運(yùn)行時(shí),每個(gè)作用域都有三個(gè)名字空間:由局部變量組成的local名字空間,由全局變量組成的global名字空間,以及python內(nèi)建模塊的builtins名字空間,在查詢一個(gè)變量時(shí),搜索順序?yàn)閘ocal->global->builtins,即局部變量屏蔽全局變量,全局變量屏蔽內(nèi)建變量。
python的global名字空間是動態(tài)的,即每遇到一個(gè)賦值語句(def與class也屬于賦值語句),global名字空間都可能發(fā)生變化。
global名字空間的動態(tài)變化
print(dir())
a = 1
print(dir())
b = 2
print(dir())
輸出結(jié)果
1 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
2 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']
3 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b']
從輸出結(jié)果可以看出,global名字空間是動態(tài)增加的。
這意味著,雖然位于global名字空間的變量叫做全局變量,它的作用范圍也不是全局位置,它只作用于第一次賦值之后的位置。因?yàn)橹挥性谧兞抠x值初始化的時(shí)候,它才會被加入到global名字空間中。
函數(shù)和類搜索的global名字空間是調(diào)用位置的global名字空間,與定義位置無關(guān)
def f(): print(a) try: f() except Exception as e: print(e) a = 2 f()
輸出結(jié)果
name 'a' is not defined
2
函數(shù)f打印全局變量a,a在第9行定義。在第五行調(diào)用f的時(shí)候,a不在global名字空間中,所以會輸出錯(cuò)誤信息,在第十行再次調(diào)用函數(shù)f時(shí),a已經(jīng)加入了global名字空間,所以能夠打印出a。
python為了提高效率,local名字空間是靜態(tài)實(shí)現(xiàn)的,因?yàn)閷τ谝粋€(gè)函數(shù)來說,它所包含的局部變量是明確已知的。
函數(shù)的local名字空間是靜態(tài)的
a = 4
def f():
try:
print(a)
except Exception as e:
print(e)
a = 1
f()
輸出結(jié)果
local variable 'a' referenced before assignment
在打印a的時(shí)候,在local名字空間中找到了a,但是這時(shí)候a并沒有賦值初始化,所以拋出異常。這也說明了local名字空間與global名字空間不同,它會在一開始就把所有的局部變量加入到名字空間中。
總結(jié):
1. python是靜態(tài)作用域,變量初始化的位置決定了它的作用域,而與變量調(diào)用的位置無關(guān)
2. global名字空間是動態(tài)的,不同位置的global名字空間不同,local名字空間是靜態(tài)的,局部變量在整個(gè)局部作用域內(nèi)可見。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳細(xì)解析Python當(dāng)中的數(shù)據(jù)類型和變量
這篇文章主要介紹了Python當(dāng)中的數(shù)據(jù)類型和變量,是Python學(xué)習(xí)當(dāng)中的基礎(chǔ)知識,需要的朋友可以參考下2015-04-04
python使用tomorrow實(shí)現(xiàn)多線程的例子
今天小編就為大家分享一篇python使用tomorrow實(shí)現(xiàn)多線程的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
Python調(diào)用Ollama庫本地大語言模型使用詳解
ollama是一個(gè)用于調(diào)用本地大語言模型的Python庫,提供了簡單、高效的API接口,下面文章詳細(xì)介紹了如何安裝、使用、設(shè)置自定義參數(shù)、集成流式生成、錯(cuò)誤處理以及與其他工具集成,需要的朋友可以參考下2025-02-02
Python輕量級ORM框架Peewee訪問sqlite數(shù)據(jù)庫的方法詳解
這篇文章主要介紹了Python輕量級ORM框架Peewee訪問sqlite數(shù)據(jù)庫的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了ORM框架的概念、功能及peewee的安裝、使用及操作sqlite數(shù)據(jù)庫的方法,需要的朋友可以參考下2017-07-07
python PyQt5/Pyside2 按鈕右擊菜單實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了python PyQt5/Pyside2 按鈕右擊菜單,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-08-08
wxPython:python首選的GUI庫實(shí)例分享
wxPython是Python語言的一套優(yōu)秀的GUI圖形庫。允許Python程序員很方便的創(chuàng)建完整的、功能鍵全的GUI用戶界面。 wxPython是作為優(yōu)秀的跨平臺GUI庫wxWidgets的Python封裝和Python模塊的方式提供給用戶的2019-10-10
Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)列表與元組示例詳解
這篇文章主要給大家介紹了關(guān)于Python內(nèi)置數(shù)據(jù)結(jié)構(gòu)列表與元組的相關(guān)資料,列表是順序存儲的數(shù)據(jù)結(jié)構(gòu),類似于數(shù)據(jù)結(jié)構(gòu)中的順序表,在存儲上是相連的一大塊內(nèi)存空間,在物理和邏輯上都是連續(xù)的,需要的朋友可以參考下2021-08-08

