2017-02-23 131 views
0

我曾經用C,C#和Java編程。現在我正在使用Python一段時間,但是我在理解變量作用域時遇到了一些問題,這對我來說現在非常困惑。例如:混淆變量作用域(來自外部作用域的陰影變量)

def f1(): 
    print(spam) # spam magically come from outer scope. ok... 


def f2(): 
    spam = "bbb" # assignment shadows variable from outer scope (logical result of f1) 
    print(spam) # printing local spam variable 


def f3(): 
    print(spam) # ERROR: unresolved reference 'spam' 
    spam = "ccc" # in f1 function everything was fine but adding assignment AFTER 
        # printing (in opposite to f2 function) causes error in line above 


def f4(): 
    print(spam) # nothing wrong here, assignment line below is commented 
    # spam = "ccc" 

spam = "aaa" 

爲什麼地球上的功能可能會超出其範圍之外的變量? 爲什麼從外部範圍的陰影變量是好的,但只有我們以前沒有使用它?

+1

你肯定你會在'f3'中得到'未解決的參考錯誤'?我期望在賦值之前引用錯誤'UnboundLocalError:本地變量'垃圾郵件',這是相當自我解釋的。 – kazemakase

+0

'f2'發生了什麼變化'垃圾'從'aaa'到'bbb' – mtkilic

+0

@kazemakase你說得對,我寫的錯誤是從IDE而不是運行時 – user3616181

回答

1

Python代碼在執行前被編譯爲字節碼。這意味着Python可以分析函數如何使用變量。一個變量是全球本地在一個函數,但不是兩個,它不能改變。

spamf1是全球性的,因爲它從未被分配。 spam在本地f2因爲它被分配。 f3也是如此。 spam由於spam='ccc'而在f3中位於本地。用print(spam)語句嘗試訪問本地變量,然後分配它。

您可以在函數內部使用global spam來強制聲明變量名稱爲全局變量名稱。

當地人住在當地。即使在本地命名空間中刪除一個變量之後,Python不查找名稱父範圍:

spam = 123 

def f(): 
    spam = 42 
    print(spam) # 42 
    del spam 
    print(spam) # UnboundLocalError 

f() 

如果你想分配給你需要聲明一個全局的變量:

spam = 123 

def f(): 
    global spam 
    spam = 42 
    print(spam) # 42 

f() 
print(spam) # 42 
+0

哦,我忘記了,甚至很多人都說python是從其實際編譯階段的腳本中解釋出來的。 – user3616181

+0

但爲什麼函數可以達到外部變量?這背後有什麼想法?因爲有人必須得出結論,這是一個理想的行爲 – user3616181

+0

@ user3616181因爲在Python中變量,函數和其他對象之間沒有區別。你希望能夠在你的函數定義中調用'print',不是嗎? 'print'是一個全局對象,'spam'也是。 '垃圾郵件'也可以是你想在你的其他功能中調用的函數。沒有理由不允許全局查找。我曾經想過關閉這個功能,但這竟然是[壞主意](http://stackoverflow.com/a/31023487/3005167)。 – kazemakase