1、命名空間查詢順序:
假設我們要使用變數 runoob,則 python 的查詢順序為:
直譯器會從命名空間中查詢runoob,它先從區域性空間查詢,如果找到了它就會使用區域性命名空間的變數runoob,即使全域性命名空間也有變數runoob。
這就很容易理解為什麼在函式內部宣告的區域性變數會覆蓋掉在模組中宣告的同名變數。
如果找不到變數 runoob,它將放棄查詢並引發乙個 nameerror 異常:
nameerror: name 'runoob'
isnot defined。
2、命名空間的生命週期:
def
outer_function()
: b =
20def
inner_func()
: c =
30a =
10
有四種作用域:
l(local):最內層,包含區域性變數,比如乙個函式/方法內部。
e(enclosing):包含了非區域性(non-local)也非全域性(non-global)的變數。比如兩個巢狀函式,乙個函式(或類) a 裡面又包含了乙個函式 b ,那麼對於 b 中的名稱來說 a 中的作用域就為 nonlocal。
g(global):當前指令碼的最外層,比如當前模組的全域性變數。
b(built-in): 包含了內建的變數/關鍵字等。,最後被搜尋
規則順序: l –> e –> g –>gt; b。
在區域性找不到,便會去區域性外的區域性找(例如閉包),再找不到就會去全域性找,再者去內建中找。
如下:
# python 的乙個內建值 int,我們首先將其賦值為 0,然後定義乙個函式 fun1()。
>>
>
int=
0>>
>
deffun1()
:int=1
deffun2()
:int=2
print
(int
) fun2(
)
函式 fun1() 的作用就是呼叫函式 fun2() 來列印 int 的值。
呼叫函式 fun1():
>>
> fun1(
)2
因為 local 中的 int = 2,函式將其列印出來。
將函式 fun2() 中的 int = 2 刪除 :
>>
>
int=
0>>
>
deffun1()
:int=1
deffun2()
:print
(int
) fun2(
)
呼叫函式 fun1():
>>
> fun1(
)1
>>
>
int=
0>>
>
deffun1()
:def
fun2()
:print
(int
) fun2(
)
呼叫函式 fun1():
>>
> fun1(
)0
因為 local 和 non-local 都找不到 int 的值,便去 global 中尋找,發現 int = 0 並列印。
若刪除 int = 0這一條件:
>>
>
deffun1()
:def
fun2()
:print
(int
) fun2(
)
呼叫函式 fun1():
因為 local、non-local、global 中都沒有 int 的值,便去 built-in 中尋找 int 的值,即:
>>
> fun1(
)<
class
'int'
>
1、全域性變數和區域性變數
2、global 和 nonlocal關鍵字
當內部作用域想修改外部作用域的變數時,就要用到global和nonlocal關鍵字了。
用global修改全域性變數 num:
num =
1def
fun1()
:global num # 需要使用 global 關鍵字宣告
print
(num)
num =
123print
(num)
fun1(
)print
(num)
輸出:1
123123
如果要修改巢狀作用域(enclosing 作用域,外層非全域性作用域)中的變數則需要 nonlocal 關鍵字:
def
outer()
: num =
10def
inner()
:nonlocal num # nonlocal關鍵字宣告
num =
100print
(num)
inner(
)print
(num)
outer(
)輸出:
100100
另外有一種特殊情況,假設下面這段**被執行:
a =
10def
test()
: a = a +
1print
(a)test(
)
執行後:
traceback (most recent call last)
: file "test.py"
, line 7,in
test(
) file "test.py"
, line 5
,in test
a = a +
1unboundlocalerror: local variable 'a' referenced before assignment
錯誤資訊為區域性作用域引用錯誤,因為 test 函式中的 a 使用的是區域性,未定義,無法修改。
修改 a 為全域性變數,通過函式引數傳遞,可以正常執行輸出結果為:
a =
10def
test
(a):
a = a +
1print
(a)test(a)
輸出:11
或者使用global關鍵字將函式內a宣告為全域性變數:
>>
> a =
10>>
>
deftest()
:...
global a..
. a = a+1.
..print
(a)...
>>
>
>>
> test(
)11
參考:
python3 命名空間和作用域
python 命名空間與作用域
解讀python的命名空間
命名空間和作用域
命名空間是對棧區的劃分,存放名字的地方.有了命名空間之後,就可以在棧區中存放相同的名字 存放的名字 存放的python直譯器內建的名字 存活週期 python直譯器啟動則產生,python直譯器關閉則銷毀 print input 存放的名字 只要不是函式內定義 也不是內建的,剩下的都是全域性命名空間...
命名空間和作用域
函式內部的函式只能在函式內部呼叫,不能在函式外部呼叫,通過接下來的學習你將會知道為什麼會出現這種情況。def f1 def f2 print from f2 f2 f2 nameerror name f2 is not defined 命名空間 name spaces 在記憶體管理那一章節時,我們曾...
命名空間和作用域
命名空間 就是存放名字和物件對映 繫結關係的地方 存放名字的空間 如果你想訪問乙個變數值,必須先訪問對應的命名空間拿到名字和對應的記憶體位址的繫結位址 python提前給你定義完的名字,就是存在內建命名空間,比如內建函式名 max print input 存放於檔案級別的名字,就是全域性命名空間 i...