[Python] 在巢狀函式中修改外層函式的區域變數值

[Python] 在巢狀函式中修改外層函式的區域變數值

今天在寫一個 unit-testing 的程式,下面的程式看起來很理所當然的要成功:

def test_foo():
a = 1
def bar():
a += 1
assert a == 2
bar()
assert a == 2

 

但是執行後,會說 bar() 裡的 a 沒有宣告過:

UnboundLocalError: local variable ‘a’ referenced before assignment

想想這也算是正常的,因為在 bar() 裡面的確沒有出現過 a…

 

那麼在 bar() 裡面加上 global a 呢?其實也不行:

def test_foo():
a = 1
def bar():
global a
a += 1
assert a == 2
bar()
assert a == 2

 

這樣子執行之後,出現了 NameError: global name ‘a’ is not defined 的錯誤…

這是因為 a 並不是宣告在最外面的全域範圍內…

那到底要怎麼做才對呢?

 

查了一下 stackoverflow: Python closure: Write to variable in parent scope

是說 += 會讓 python 認為左邊的變數 a 是一個區域變數,

如果將 a 改成一個 list 或 dict 或是 class object 的話就 OK 了,例如:

def test_foo():
a = [1]
def bar():
a[0] += 1
assert a[0] == 2
bar()
assert a[0] == 2

 

目前這個方法似乎是在 python 2.x 上較常見的做法,

雖然看起來有點奇怪,不過暫時只能這樣子囉~

 

(本頁面已被瀏覽過 273 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料