命名空間的小弟作用域 在這要明確一個觀點,在Python中萬物皆對象,而變數指向的就是對象。 變數可以是 類名,函數名,儲存數據的變數…… 對象可以是 類 ,被封裝的一段代碼(函數),數據…… 命名空間 命名空間是從名字到對象的映射。在Python大多數命名空間目前以字典的形式實現。變數名是“鍵”, ...
命名空間的小弟作用域
在這要明確一個觀點,在Python中萬物皆對象,而變數指向的就是對象。
變數可以是 類名,函數名,儲存數據的變數……
對象可以是 類 ,被封裝的一段代碼(函數),數據……
命名空間
命名空間是從名字到對象的映射。在Python大多數命名空間目前以字典的形式實現。變數名是“鍵”,對象(內置函數,內置常量,內置類型,函數,類,變數)是“值”。
各個命名空間是獨立的,沒有任何關係的,所以一個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。
命名空間都是有創建時間和生存期的。對於Python built-in namespace(內置命名空間——內置函數,內置常量,內置類型)組成的命名空間,它在Python解釋器啟動的時候被創建,在解釋器退出的時候才被刪除;
對於一個Python 模塊的global namespace(全局變數),它在這個模塊被 引用的時候創建,在解釋器退出的時候退出;
對於一個函數的local namespace(局部作用域),它在函數每次被調用的時候創建,函數返回的時候被刪除。
作用域
作用域只是命名空間表示大小(適用範圍)的屬性。
作用域是Python程式(文本)的某一段或某些段,在這些地方,某個命名空間中的名字可以被直接引用。這個作用域就是這個命名空間的作用域。
python中的作用域分4種情況:
- L:local,局部作用域,即函數中定義的變數;
- E:enclosing,嵌套的父級函數的局部作用域,即包含此函數的上級函數的局部作用域,但不是全局的;
- G:globa,全局變數,就是模塊級別定義的變數;
- B:built-in,系統固定模塊裡面的變數,比如int, bytearray等
搜索變數的優先順序順序
局部作用域>外層作用域>當前模塊中的全局>python內置作用域,也就是L>E>G>B。
B = str("B:built-in 內置作用域") G = "G:globa,全局變數,就是模塊級別定義的變數" print(B) # 當前模塊中的全局>python內置作用域 找B print(G) # 當前模塊中的全局 找G print(E) # 找不到E print(L) # 找不到L def f(): E = "E:enclosing,嵌套的父級函數的局部作用域" print(B) # 外層作用域>當前模塊中的全局>python內置作用域 找B print(G) # 外層作用域>當前模塊中的全局 找G print(E) # 外層作用域 找E print(L) # 找不到L def z (): L = "L:local,局部作用域,即函數中定義的變數" print(B) # 作用域局部>外層作用域>當前模塊中的全局>python內置作用域 找B print(G) # 作用域局部>外層作用域>當前模塊中的全局 找G print(E) # 作用域局部>外層作用域 找E print(L) # 作用域局部 找L
註意:在Python中,只有模塊(module),類(class)以及函數(def、lambda)才會引入新的作用域,其它的代碼塊(如if、try、for等)是不會引入新的作用域的
變數的修改
在“作用域局部>外層作用域>當前模塊中的全局>python內置作用域”中,更內層的作用域不可直接修改外層的作用域的變數,要修改要用到global關鍵字 和 nonlocal關鍵字
global關鍵字
當修改的變數是在全局作用域(global作用域)上的,就要使用global先聲明一下。
nonlocal關鍵字
global關鍵字聲明的變數必須在全局作用域上,不能嵌套作用域上,當要修改嵌套作用域(enclosing作用域,外層非全局作用域)就需要nonlocal關鍵字了
B = str("B:built-in 內置作用域") G = "G:globa,全局變數,就是模塊級別定義的變數" def f(): E = "E:enclosing,嵌套的父級函數的局部作用域" def z (): L = "L:local,局部作用域,即函數中定義的變數" global B B = "修改全局作用域的變數" nonlocal E E = "修改嵌套作用域的變數"
歡迎評論,番茄,雞蛋都砸過來吧!!!