2017-06-12 63 views
2

我希望更好地理解事情,爲什麼這個工作沒有將函數fct中的list c聲明爲全局變量?變量a是不是這樣?Python - 列表變量的sccope

def fct(): 
    global a  # have to declare this for "a" to work, but not for c[] 
    print(a,c) # by not declaring "a" as global, caused this to flag 
        # "accessing a without assignment", which I understand why, 
        # but why c[] needn't declaration 
    c[1]=5 
    a=234 

c=[0,0] 
a=11 
fct() 
+5

你沒有分配給'c'。通過告訴*來設置給定索引的值,你*突變*'c'。換句話說,'c [...] = ...'與'c = ...'大相徑庭。 –

+0

https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules –

+0

簡短的答案是因爲列表是可變的,整數是不可變的。 – Anup

回答

1

執行之前好了這個問題,可能需要解釋的一點。

PEP 3104指出:

在支持嵌套作用域大多數語言,代碼可以指或重新綁定(分配給)任何名稱在最近的封閉範圍。目前,Python代碼可以引用任何封閉作用域中的名稱,但它只能在兩個作用域中重新綁定名稱:本地作用域(通過簡單賦值)或模塊全局作用域(使用全局聲明)。

有兩件事情你必須瞭解這裏要說的是:

  • 綁定:創建一個名稱,一個值綁定到它。 例如>>> a=10 創建一個變量a並給它賦值10。

  • 重新綁定:更改綁定到名稱的值。 例如>>> a=10;a=5 綁定值10然後將5重新綁定到'a'本身。

因此,它明確指出它只能在本地範圍重新綁定名稱。

例子:

def func(): 
    a=5 
    print(a) 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

輸出:

a in the program 
10 
a in func() 
5 

現在移除func()a=5,你會得到:

a in the program 
10 
a in func() 
10 

會發生什麼事是a被發現是10它被打印。

現在做到這一點:

def func(): 
    print(a) 
    a=5 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

你得到這樣的:

UnboundLocalError: local variable 'a' referenced before assignment 

,如果你在一個函數給a=5會發生什麼?

重新綁定現在發生,而不是創建一個新的局部變量a = 5。

所以,

  • ,如果你不寫a=5後/它只是默認打印全局變量a之前print聲明。

  • 但是如果你print(a)之前寫a=5它創建一個局部變量a,然後結合(注意:不是重新綁定,但綁定)值5它。

  • 如果你寫a=5print(a)後它就會困惑,爲什麼你引用一個變量(局部變量)還未被創建。

然而,因爲任何分配的名稱隱含聲明該名稱是本地的,也不可能在外部範圍(除了當全局聲明迫使名稱是全球性的)重新綁定的名稱。

所以如果你使用global a打印(一)高興地打印出全球a10,然後通過結合5到創建一個新的局部變量a=5

global a 
print(a) 
a=5 
print(a) 

輸出:

def func(): 
    global a 
    print(a) 
    a=5 
    print(a) 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

但是,這不是你喜歡listdict及其他物體的情況。 在這種情況下,您只需修改通過常規名稱查找找到的現有全局對象(更改列表條目就像調用列表中的成員函數,它不是名稱重新綁定)。

因此,它工作正常,沒有任何錯誤。希望你明白一些事情。

+0

這就解釋了爲什麼'global a'是​​必需的;但是OP詢問爲什麼'global c'不是必需的。 –

0

如果用一句話global這意味着你可以在一個全局變量寫,但我只是想閱讀它不需要使用global

你不需要在函數體中聲明ca,因爲你已經聲明他們只是fct()

+0

感謝您將更好的綁定點指向列表中的「c」,而不是更改它的一個成員。 – ffrree