之所以這兩個一起寫,是因為Lec3對我而言沒什麼內容,Python的東西不多。
Lec3的一個核心是:一個程式會在什麼時候停止?我認為有三種情況:1. 返回正確的值。2. 返回錯誤的值。3. 報錯
Python:
for variable in range(start, end):
statement
Lec4裡function終於閃亮登場了。function由三部分組成:名字,參數和方法體,function的特點:Decomposition和Abstraction,我的理解是代碼複用和封裝。當然,人家講的更有道理,Decomposition是指將一個系統分解為相互獨立、可管理的子部分。Abstraciton則是建立了一個黑盒,輸入獲得輸出。
當方法被調用時,將產生下面這些操作:
- 形參綁定到實參的值
- 在進入函數時,將產生一個新的Scope
Python中一個很有趣的概念是Scope。Scope是指name到object的映射,變數、函數都有自己的Scope。Scope也叫stack frames。我認為stack frame來自於編譯器的實現,程式在運行時實際就是在不斷的進行壓棧、彈棧,這方面的內容可以參考《C專家編程》。下面關於Scope的介紹,參考自:http://www-inst.eecs.berkeley.edu/~selfpace/cs9honline/Q2/scope.html
有關Python中的Scope,要記住三點:
1. Scope中所有的name都same
學習Python時首先要記住的是Python中的一切都是有名字的,比如數字,字串,函數,類型,變數等。Python中所有的name都same,這與Java或C++不同,不同類型的name可以一樣,例如類blerg可以和變數blerg同時存在。執行下面的代碼,可以更好地理解這一點。
spoon = 2 + 2print spoondef spoon(x): return x + 3print spoonspoon = 'foo'print spoon
在上面的Python代碼中,只有一個name spoon。spoon首先是一個數字,然後變成一個函數,最後成為字串的name。
2. name的Scope是它所在的檔案,類或函數
每個name都屬於一個namespace(在scheme中叫“environment”)。
def genius(): x = 2 + 2 print 'two plus two is', x
在上面的例子中,x的Scope為函數genius。當程式進入函數時,會首先將genius壓入棧中,然後x的範圍就是那個棧幀(StackFrame)。
x = 2 + 2def genius(): print 'two plus two is', xdef dummy(): x = 3 print 'two plus two is', xdef gullible(x): print 'two plus two is', xgenius()dummy()print xgenius()gullible(5)
將上面的程式存到一個檔案中,如scopedemo.py,執行之,會出現有趣的結果。
上面的代碼首先為x建立了一個File範圍的Scope,genius函數建立了一個scope,但genius的scope中並不存在一個x。當在genius中引用x的時候,Python首先在genius的scope中尋找,若沒找到,則去包含此Scope的外層Scope尋找,因此genius中輸出x的值為4,如所示:
在genius中引用的是外部Scope定義的x。
在dumm()中,有自己的x定義,因此這裡x引用的是內部Scope的x。
在gullible(x)中,形參x在gullible()函數內聲明了一個
3. name屬於它所在的namespace
在一個namespace中,name的範圍是整個namespace,而不是從其聲明的位置開始。例如在dummy中,即使x = 3出現在dummy()的最後一行,x的scope仍然是dummy函數。如下面的例子:
x = 1def kumquat(): x = 5 print xdef gazebo(): print x # many lines of code... # many lines of code... # many lines of code... x = 5def hullabaloo(y): if y > 3: x = 5 print xkumquat()gazebo()hullabaloo(1)hullabaloo(6)
在調用gazebo()的時候,儘管對x的指派陳述式在最後,但其Scope卻是整個函數,因此gazebo()的print x語句會報錯,而不是輸出1.
如何將一個變數的值傳遞到外層的scope呢?可以使用global關鍵字實現,global關鍵字將使變數的Scope擴充為File級。
x = 2def foible(): x = x + 1def spatula(): global x x = x + 1print xfoible()print xspatula()print x
在上面的代碼中,spatula()執行之後x的值變為3,因為spatula()中x的Scope是File。