2011-12-05 30 views
2

我有一個非常簡單,也許愚蠢的問題:爲什麼在使用函數定義函數後能夠定義一個變量?

爲什麼這樣嗎?

def print_list(): 
    for student in student_list: 
     print(student) 

student_list = ["Simon", "Mal", "River", "Zoe", "Jane", "Kaylee", "Hoban"] 
print_list() 

的方式我已經認識到的功能和參數,功能print_list()不應該承認student_list,因爲我沒有將其指定爲函數的參數。

+1

感謝大家給出的真正令人印象深刻的和翔實的答案。我會更多地閱讀全球範圍,儘管我從你的定義中瞭解它。但我不確定我是否完全同意我的問題編輯。我完全理解,在序列或代碼執行過程中,列表分配發生在函數被調用之前,因此對我而言,由於Python知道在全局範圍內尋找變量,所以它可以使用代碼中定義的內容。 – Vortex

回答

1

在Python中,變量被創建時,你分配他們。在你的情況,student_list是在全球範圍內分配的,所以它是一個全局變量(全球範圍的東西,不在你的函數中。)

當Python在一個不是局部變量的函數內部遇到一個變量(也就是說,它沒有作爲參數傳入並且沒有在函數內部賦值)時,它自動地y在全局範圍內查找變量。

如果你想知道什麼global聲明的目的是,因爲全局變量已經可以看到裏面的功能:global讓你重新分配一個全局變量,並將它帶全局生效。例如:

def b(): 
    global a 
    a = 5 

a = 4 
print(a) # prints 4 
b() 
print(a) # prints 5 

在大多數情況下,你不需要global發言,我建議你不要使用它,尤其是直到你在Python老練多了。 (儘管經驗豐富的Python程序員往往不會使用global)。

+0

這非常有道理。謝謝約翰!我在你所建議的背景下了解了全球聲明。我也明白爲什麼不推薦(調試混亂,意外的結果,沒有單一的控制來源和價值變化等)。我不知道的是全球範圍這個詞的存在(如果不是在功能上,而不是在課堂上)。 – Vortex

6

當您撥打print_list()時,您有student_list定義爲全局變量。

+0

哇,你很快!感謝您的回覆。現在想到兩個問題: 1.爲什麼我的列表被定義爲全局變量?我認爲我必須使用全球聲明。 2.以上代碼與此代碼之間的區別是什麼? DEF print_list(列表): 對於i在列表: 打印(ⅰ) student_list = [ 「西蒙」, 「瑪」, 「河」, 「佐伊」, 「簡」, 「王小強」, 「霍本」 ] print_list(student_list) – Vortex

+0

這是由於python的範圍界定行爲。爲了理解這種行爲,你可以在這裏閱讀教程的相關部分 - > http://docs.python.org/tutorial/classes.html#python-scopes-and-namespaces – wim

+0

1. Python逐行進行構建程序結構。你可以說沒有縮進的東西是全局的。你有一個函數聲明,一個列表和一個函數調用。函數調用實際上執行你的函數,但是你可以說從這個角度來看它和其他的一樣(或者@wim剛剛說過的)。 –

1

我的理解是,你的程序有3個部分

方式
  1. 定義print_list()
  2. INITIALISE student_list(全局變量)
  3. 調用print_list()

當你調用print_list(),student_list已經存在。另外,在一個函數中,你可以在其中搜索一個變量(student_list)的範圍: 1.本地範圍(它會失敗,因爲你沒有定義它,只能參考) 2.全局範圍(它會成功,因爲它只是初始化

+0

我很困惑! :)我瞭解到一個函數需要接收來自程序的參數,否則當它在函數中被引用時它不會識別它們。是否有可能讓我感到困惑,而將這兩者分開只是一種好的做法?這對大多數編程語言來說都是如此 – Vortex

+0

呵呵,「需要收到一份arg ..否則」並不準確。所有現代語言都有一個範圍概念 - http://en.wikipedia.org/wiki/Scope_(computer_science)。它基本上說,當引用一個變量時,編譯器/解釋器會嘗試在它聲明的塊中找到它(函數在你的情況下)。如果失敗了,它會上升一級,直到找到它爲止。 –