2016-10-17 172 views
0
A=[] 

def main(): 
    global A 
    A=[1,2,3,4,5] 
    b() 

def b(): 
    if(len(A)>0): 
     A=[7,8,9] 
    else: 
     if(A[3]==4): 
      A.remove(2) 

main() 

此代碼給出錯誤行A.remove(2)給出的理由:「UnboundLocalError:轉讓前‘A’引用的局部變量」全局變量的Python

但名單是全球性的,並肯定它有已在main()函數中初始化。請解釋爲什麼這會給出錯誤?

由於A在b函數中已經被初始化了,這會導致錯誤嗎?

+0

工作對我蠻好,關於Python 3.4.3和Python 2.7.12。 – Li357

+1

無法重現。對我來說工作得很好,Python 3.5。這是你的真實代碼嗎?因爲你的真實代碼中可能存在某些東西,你認爲*並不會導致實際的問題。 – idjaw

+0

在python 2.7,3.5上工作 – Juggernaut

回答

2

您收到這是因爲當你執行你的函數此分配的原因:

A = [7, 8, 9] 

的解釋現在看到A作爲本地綁定變量。所以,現在會發生什麼,看着這個條件:

if(len(A)>0): 

真要扔你第一UnboundLocalError例外,因爲,因爲事實上,如上所述,你從未宣佈過在你的b功能global A還創建了一個本地綁定變量A = [7, 8, 9],在嘗試使用本地A之前,您已經聲明瞭它。

你居然面臨着同樣的問題,當您嘗試這樣做:

A.remove(2) 

相對於你的代碼解決這個問題,簡單地聲明global A放回你b()功能。

def b(): 
    global A 
    if(len(A)>0): 
     A=[7,8,9] 
    else: 
     if(A[3]==4): 
      A.remove(2) 

然而,要做到這一點就更好了,理想和推薦的方法是不使用全局,只是傳遞參數給你的函數

A = [1, 2, 3, 4] 


def main(list_of_things): 
    # do whatever operations you want to do here 
    b(list_of_things) 

def b(list_of_things): 
    # do things with list_of_things 

main(A) 
+0

你能否澄清*爲什麼會拋出錯誤? – Li357

+0

@AndrewLi增加了一些清晰度。 – idjaw

0

您必須在分配給它的任何函數中聲明變量global

def b(): 
    global A 
    if some_condition: 
     A.append(6) 
    else: 
     A.remove(2) 

如果沒有b()範圍內聲明Aglobal,Python的假定A屬於在B()的命名空間。您可以在範圍內讀取它,但不能編輯它(所做的任何更改將不會堅持到真正A

你允許在設定一些功能A = ...會在裏面工作,但只有的功能。

如果你嘗試變異函數的內部,而無需在函數的名字空間定義A,那麼Python會告訴你,你正試圖變異變量的範圍之外與UnboundLocalError

通過宣佈Aglobal,解釋者知道你的意思是編輯全局變量。

我假設你的意思是你的代碼看起來是這樣的(否則,它運行良好)

A=[] 

if __name__ == '__main__': 
    def main(): 
     global A 
     A=[1,2,3,4,5] 
     b() 

    def b(): 
     global A 
     if some_condition: 
      A=[7,8,9] 
     else: 
      A.remove(2) 
     print A 

    main() 
    print A 

print A