任何人都可以解釋下面的代碼異常。它只在將display()中的var sub更改爲另一個名稱時才起作用。也沒有全局變量sub。所以發生了什麼事 ?Python中的UnboundLocalError令人困惑
def sub(a, b):
return a - b
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
任何人都可以解釋下面的代碼異常。它只在將display()中的var sub更改爲另一個名稱時才起作用。也沒有全局變量sub。所以發生了什麼事 ?Python中的UnboundLocalError令人困惑
def sub(a, b):
return a - b
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
這是最初的評論。 OP發現這個有用的答案。因此,我將其重新發布爲答案
最初,sub
是一個函數。然後,它成爲函數的返回值。所以當你說print sub
時,python不知道你指的是哪一個sub
。
編輯:
首先定義一個函數sub
。現在,Python知道什麼sub
是。
當您創建一個變量並嘗試分配給它(比如x = 2
)時,python會評估=
右側的內容,並將評估值指定爲左側內容的值的=
。因此,右邊的所有內容都應該實際計算。
所以如果你的陳述是x = x+1
,那麼x
更好的是在該行之前賦值給它;並且之前定義的x
必須是與1
的添加兼容的某種類型。
但是,假設x
是一個函數,你犯了一個在其他一些函數調用x
變量,並試圖給它,使用功能x
計算的值,那麼這真的開始迷惑蟒蛇哪些x
你是指至。這是真的this answer過於簡單化了,這很好地解釋變量的作用域和Python函數陰影的一個更好的工作
這太簡單了 - 如果你在'display'裏面說'sub = 1',你仍然會隱藏函數名,這是完全合法的。問題在於,在相同範圍內名稱被* used *和*分配給*。請參閱[本答案](http://stackoverflow.com/a/12092094/1110381)瞭解關於python中閉包的更詳細說明。 – l4mpi
@ l4mpi:夠公平的。我真的應該在星期一早上停止回答問題,然後再開始我的咖啡。謝謝你的澄清 – inspectorG4dget
的Python開始執行代碼,並得到了功能第一
def sub(a, b):
return a - b
所以執行這個解釋得到後作爲函數的sub
。現在,當走到下一行就發現
def display():
sub = sub(2,1) // if change to sub1 or sth different to sub, it works
print sub
所以第一線sub = sub (2, 1)
將sub
功能轉換爲sub
變量。從這個函數返回sub
變量。所以它造成的問題。
這完全不是發生了什麼... – l4mpi
任何變量分配給內部的範圍被視爲一個局部變量(除非聲明它global
,或者,在python3,nonlocal
),這意味着它在周邊範圍不查找。
一個簡單的例子用了同樣的錯誤:
def a(): pass
def b(): a = a()
現在,考慮在這裏所涉及的不同範圍:
全局命名空間包含a
和b
。
函數a
不包含局部變量。
功能b
包含一個分配給a
- 這意味着它被解釋爲一個局部變量和陰影從外範圍的函數a
(在這種情況下,在全球範圍內)。由於在調用之前尚未在b
內定義a
,所以它是一個未綁定的局部變量,因此是UnboundLocalError。這是完全一樣的,如果你這樣寫的:
def b(): x = x()
這個解決方案很簡單:爲sub
調用的結果選擇一個不同的名稱。
def display():
value = sub(2,1) #UnboundLocalError here...
print value
sub = "someOtherValue" #because you assign a variable named `sub` here
這是因爲局部變量的列表是:錯誤本來還是發生了,如果你寫了這樣的功能 -
要注意,使用和分配的秩序並沒有區別是很重要的當python解釋器創建函數對象時生成。
對於使用的每個變量,Python都會確定它是本地變量還是非本地變量。引用未知變量將其標記爲非局部變量。之後重用相同的名稱作爲本地變量被認爲是程序員的錯誤。
考慮這個例子:
def err():
print x # this line references x
x = 3 # this line creates a local variable x
err()
這給你
Traceback (most recent call last):
File "asd.py", line 5, in <module>
err()
File "asd.py", line 2, in err
print x # this line references x
UnboundLocalError: local variable 'x' referenced before assignment
會發生什麼情況基本上是Python的跟蹤到的代碼名稱的所有引用。當它讀取行print x
Python知道x
是來自外部作用域(upvalue或global)的變量。但是,在x = 3
中,x
被用作局部變量。由於這是代碼中的不一致,Python引發了一個UnboundLocalError
以引起程序員的注意。
最初,'sub'是一個函數。然後,它成爲函數的返回值。所以當你說'print sub'時,python不知道你指的是哪個'sub' – inspectorG4dget
@ inspectorG4dget:你的解釋非常簡單。謝謝 –