1. 程式人生 > >函數作用域與名稱空間

函數作用域與名稱空間

未定義 函數的調用 oca assign 需要 無法 () 是什麽 影響

函數作用域與名稱空間

首先我們看看下面的代碼:

a = 10
def f1():
    print(a)
f1()    10
#不會報錯

a = 10
def f1():
    print(a)
    a = 1
f1() 

#UnboundLocalError: local variable ‘a‘ referenced before assignment
這句話的含義是變量a在定義前調用

為什麽會出現這樣的錯誤呢?

這就要從函數的作用域與名稱空間說起了

什麽是名稱空間?

顧名思義,名稱空間就是存放名字的地方,python中名稱空間有三種:

  • 內置名稱空間
  • 全局名稱空間
  • 局部名稱空間

名稱空間的加載順序為:內置名稱空間----->全局名稱空間------->局部名稱空間

名稱空間的查找順序剛好相反:局部名稱空間----->全局名稱空間-----> 內置名稱空間

需要註意的是在全局無法查看局部的名稱,在局部卻可以查看全局的

作用域是什麽?

作用域是能夠影響的範圍空間,作用域範圍又分為兩種:

  • 全局範圍(內置名稱空間與全局名稱空間屬於該範圍):全局存活,局部有效
  • 局部範圍(局部名稱空間屬於該範圍):臨時存活,局部有效

其中,作用域關系是在函數定義階段就已經固定的,與函數的調用位置無關


清楚了這些後,上面的錯誤大家就應該可以明白了。
在執行函數f1,打印a的時候,會先從自己的名稱空間中找a,如果沒有找到,就會去外面一層的名稱空間去找,最後到全局去找,所以,上面代碼不會報錯,但是下面的代碼就多了一行對a的賦值,就報錯了,原因就是代碼是從上之下執行的,在還沒有對a賦值前f1中是沒有a的,所以會出現未定義先使用的錯誤,

解決方法:
在使用前先聲明 nonlocal

a = 10 def f1(): a = 2 def f2(): nonlocal a a += 1 f2() f1()

函數作用域與名稱空間