我在這裏做錯了什麼?Python中的UnboundLocalError
counter = 0
def increment():
counter += 1
increment()
上面的代碼會拋出一個UnboundLocalError
。
我在這裏做錯了什麼?Python中的UnboundLocalError
counter = 0
def increment():
counter += 1
increment()
上面的代碼會拋出一個UnboundLocalError
。
Python沒有變量聲明,所以它必須弄清楚的變量本身scope。它是通過一個簡單的規則來實現的:如果函數內部有一個變量賦值,該變量被認爲是本地的。 [1]因此,線
counter += 1
隱含使得counter
本地increment()
。儘管如此,嘗試執行此行將在分配之前嘗試讀取本地變量counter
的值,從而產生UnboundLocalError
。 [2]
如果counter
是一個全局變量,該global
關鍵字會有所幫助。如果increment()
是本地函數,並且counter
是本地變量,則可以在Python 3.x中使用nonlocal
。
python 3 docs has a [faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value](https://docs.python.org/3/faq/programming .html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value)通過[unboundlocalerror-local-variable-l-referenced-before-assignment-python](http:// stackoverflow.com/questions/21456739/unboundlocalerror-local-variable-l-referenced-before-assignment-python) – here 2014-05-04 07:19:41
一個注意到了我,我有一個變量聲明在文件的頂部,我可以讀取一個函數沒有問題,但是要寫入我已經在文件頂部聲明的變量,我必須使用全局變量。 – mouckatron 2018-02-06 14:35:46
要修改函數內的全局變量,必須使用全局關鍵字。
當您嘗試這樣做沒有行
global counter
增量的定義內,局部變量命名的計數器產生,從而讓你從打亂計數器變量,整個程序可能取決於。
請注意,您只需要在修改變量時使用全局;你可以在增量內讀取計數器而不需要全局聲明。
您需要使用global statement讓你修改的全局變量計數器,而不是一個局部變量:
counter = 0
def increment():
global counter
counter += 1
increment()
如果counter
在規定的封閉範圍是不是全球範圍內,關於Python 3.x你可以使用nonlocal statement。在關於Python 2.x中相同的情況下,你就沒有辦法重新分配到外地名counter
,所以你需要做counter
可變和修改:
counter = [0]
def increment():
counter[0] += 1
increment()
print counter[0] # prints '1'
酷..它工作+1 – 2016-10-06 06:26:52
它的工作表示感謝。 – 2016-11-22 09:05:15
試試這個
counter = 0
def increment():
global counter
counter += 1
increment()
Python在默認情況下具有詞法作用域,這意味着雖然封閉作用域可以訪問其封閉作用域中的值,但它不能修改它們(除非它們是用關鍵字global
聲明爲全局的)。
的封蓋結合在值封閉環境的名稱在當地環境。然後本地環境可以使用綁定值,甚至可以將該名稱重新分配給其他名稱,但不能修改封閉環境中的綁定。
在你的情況下,你試圖把counter
當作局部變量而不是綁定值。請注意,此代碼,結合在封閉的環境中分配的x
值,正常工作:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
要回答這個問題在你的主題行,*是的,有在Python關閉,除非他們只是內部應用一個函數,還有(在Python 2.x中)它們是隻讀的;您不能將該名稱重新綁定到不同的對象(但如果該對象是可變的,則可以修改其內容)。在Python 3.x中,可以使用nonlocal
關鍵字來修改閉包變量。
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
*原始問題的標題問到Python中的閉包。
爲什麼你的代碼拋出一個UnboundLocalError
的原因已在其他答案中得到很好的解釋。
但在我看來,你正在試圖建立一個像itertools.count()
一樣工作的東西。
那麼你爲什麼不嘗試一下,看看它是否適合你的情況:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
@ZeroPiraeus:你爲什麼錘問題與40K +的看法,這是「UnboundLocalError」的第一個結果在谷歌,作爲一個幾乎相同的新問題,你回答的副本,而不是簡單地發佈你的答案*在這裏*? – vaultah 2017-01-03 00:26:05
這個問題和它目前標記爲重複的問題正在[Python聊天室](http://chat.stackoverflow.com/transcript/message/34899645#34899645)中討論。 – 2017-01-03 01:30:44
這裏的許多答案都表示使用'global',儘管有效,但在其他選項存在的情況下,通常不推薦使用可修改的全局變量。 – 2017-01-03 01:34:48