SICP Python描述 1.1 引言

發表於2016-08-08

電腦科學是一個極其寬泛的學科。全球的分散式系統、人工智慧、機器人、圖形、安全、科學計算,計算機體系結構和許多新興的二級領域,每年都會由於新技術和新發現而擴充套件。電腦科學的快速發展廣泛影響了人類生活。商業、通訊、科學、藝術、休閒和政治都被計算機領域徹底改造。

電腦科學的巨大生產力可能只是因為它構建在一系列優雅且強大的基礎概念上。所有計算都以表達資訊、指定處理它所需的邏輯、以及設計管理邏輯複雜性的抽象作為開始。對這些基礎的掌握需要我們精確理解計算機如何解釋程式以及執行計算過程。

這些基礎概念在伯克利長期教授,使用由Harold Abelson、Gerald Jay Sussman和Julie Sussman創作的經典教科書《電腦科學的構造與解釋》(SICP)。這個講義大量借鑑了這本書,原作者慷慨地使它可用於改編和複用。

我們的智力之旅一旦出發就不能回頭了,我們也永遠都不應該對此有所期待。

我們將要學習計算過程的概念。計算過程是計算機中的抽象事物。在演化中,過程操縱著叫做資料的其它事物。過程的演化由叫做程式的一系列規則主導。人們創造程式來主導過程。實際上,我們使用我們的咒語來憑空創造出計算機的靈魂。

我們用於創造過程的程式就像巫師的魔法。它們由一些古怪且深奧的程式語言中的符號表示式所組成,這些語言指定了我們想讓過程執行的任務。

在一臺工作正確的計算機上,計算過程準確且嚴謹地執行程式。所以,就像巫師的學徒那樣,程式設計師新手必須學會理解和預測他們的魔法產生的結果。

–Abelson & Sussman, SICP (1993)

1.1.1 在Python中程式設計

語言並不是你學到的東西,而是你參與的東西。

Arika Okrent

為了定義計算過程,我們需要一種程式語言,最好是一種許多人和大量計算機都能懂的語言。這門課中,我們將會使用Python語言。

Python是一種廣泛使用的程式語言,並且在許多職業中都有它的愛好者:Web程式設計師、遊戲工程師、科學家、學者,甚至新程式語言的設計師。當你學習Python時,你就加入到了一個數百萬人的開發者社群。開發者社群是一個極其重要的組織:成員可以互相幫助來解決問題,分享他們的程式碼和經驗,以及一起開發軟體和工具。投入的成員經常由於他們的貢獻而出名,並且收到廣泛的尊重。也許有一天你會被提名為Python開發者精英。

Python語言自身就是一個大型志願者社群的產物,並且為其貢獻者的多元化而自豪。這種語言在20世紀80年代末由Guido van Rossum設計並首次實現。他的Python3教程的第一章解釋了為什麼Python在當今眾多語言之中如此流行。

Python適用於作為教學語言,因為縱觀它的歷史,Python的開發者強調了Python程式碼對人類的解釋性,並在Python之禪中美觀、簡約和可讀的原則下進一步加強。Python尤其適用於課堂,因為它寬泛的特性支援大量的不同程式設計風格,我們將要探索它們。在Python中程式設計沒有單一的解法,但是有一些習俗在開發者社群之間流傳,它們可以使現有程式的閱讀、理解,以及擴充套件變得容易。所以,Python的靈活性和易學性的組合可以讓學生們探索許多程式設計正規化,之後將它們新學到的知識用於數千個正在開發的專案中。

這些講義通過使用抽象設計的技巧和嚴謹的計算模型,來快速介紹Python的特性。此外,這些講義提供了Python程式設計的實踐簡介,包含一些高階語言特性和展示示例。通過這門課,學習Python將會變成自然而然的事情。

然而,Python是一門生態豐富的語言,帶有大量特性和用法。我們講到基本的電腦科學概念時,會刻意慢慢地介紹他們。對於有經驗的學生,他們打算一口氣學完語言的所有細節,我們推薦他們閱讀Mark Pilgrim的書Dive Into Python 3,它在網上可以免費閱讀。這本書的主題跟這門課極其不同,但是這本書包含了許多關於使用Python的寶貴的實用資訊。事先告知:不像這些講義,Dive Into Python 3需要一些程式設計經驗。

開始在Python中程式設計的最佳方法就是直接和直譯器互動。這一章會描述如何安裝Python3,使用直譯器開始互動式會話,以及開始程式設計。

1.1.2 安裝Python3

就像所有偉大的軟體一樣,Python具有許多版本。這門課會使用Python3最新的穩定版本(本書編寫時是3.2)。許多計算機都已經安裝了Python的舊版本,但是它們可能不滿足這門課。你應該可以在這門課上使用任何能安裝Python3的計算機。不要擔心,Python是免費的。

Dive Into Python 3擁有一個為所有主流平臺準備的詳細的安裝指南。這個指南多次提到了Python3.1,但是你最好安裝3.2(雖然它們的差異在這門課中非常微小)。EECS學院的所有教學機都已經安裝了Python3.2。

1.1.3 互動式會話

在Python互動式會話中,你可以在提示符>>>之後鍵入一些Python程式碼。Python直譯器讀取並計算你輸入的東西,並執行你的各種命令。

有幾種開始互動式會話的途徑,並且具有不同的特性。把它們嘗試一遍來找出你最喜歡的方式。它們全部都在背後使用了相同的直譯器(CPython)。

  • 最簡單且最普遍的方式就是執行Python3應用。在終端提示符後(Mac/Unix/Linux)鍵入python3,或者在Windows上開啟Python3應用。(譯者注:Windows上設定完Python的環境變數之後,就可以在cmd或PowerShell中執行相同操作了。)
  • 有一個更加使用者友好的應用叫做Idle3(idle3),可用於學習這門語言。Idie會高亮你的程式碼(叫做語法高亮),彈出使用提示,並且標記一些錯誤的來源。Idle總是由Python自帶,所以你已經安裝它了。
  • Emacs編輯器可以在它的某個緩衝區中執行互動式會話。雖然它學習起來有些挑戰,Emacs是個強大且多功能的編輯器,適用於任何語言。請閱讀61A的Emacs教程來開始。許多程式設計師投入大量時間來學習Emacs,之後他們就不再切換編輯器了。

在所有情況中,如果你看見了Python提示符>>>,你就成功開啟了互動式會話。這些講義使用提示符來展示示例,同時帶有一些輸入。

控制:每個會話都保留了你的歷史輸入。為了訪問這些歷史,需要按下<Control>-P(上一個)和<Control>-N(下一個)。<Control>-D會退出會話,這會清除所有歷史。

1.1.4 第一個例子

想像會把不知名的事物用一種形式呈現出來,詩人的筆再使它們具有如實的形象,空虛的無物也會有了居處和名字。

–威廉·莎士比亞,《仲夏夜之夢》

為了介紹Python,我們會從一個使用多個語言特性的例子開始。下一節中,我們會從零開始,一步一步構建整個語言。你可以將這章視為即將到來的特性的預覽。

Python擁有常見程式設計功能的內建支援,例如文字操作、顯示圖形以及網際網路通訊。匯入語句

為訪問網際網路上的資料載入功能。特別是,它提供了叫做urlopen的函式,可以訪問到統一資源定位器(URL)處的內容,它是網際網路上的某個位置。

語句和表示式:Python程式碼包含語句和表示式。廣泛地說,計算機程式包含的語句

  1. 計算某個值
  2. 或執行某個操作

語句通常用於描述操作。當Python直譯器執行語句時,它執行相應操作。另一方面,表示式通常描述產生值的運算。當Python計算表示式時,就會計算出它的值。這一章介紹了幾種表示式和語句。

賦值語句

將名稱shakespeare和後面的表示式的值關聯起來。這個表示式在URL上呼叫urlopen函式,URL包含了莎士比亞的37個劇本的完整文字,在單個文字檔案中。

函式:函式封裝了運算元據的邏輯。Web地址是一塊資料,莎士比亞的劇本文字是另一塊資料。前者產生後者的過程可能有些複雜,但是我們可以只通過一個表示式來呼叫它們,因為複雜性都塞進函式裡了。函式是這一章的主要話題。

另一個賦值語句

將名稱words關聯到出現在莎士比亞劇本中的所有去重詞彙的集合,總計33,721個。這個命令鏈呼叫了readdecodesplit,每個都操作銜接的計算實體:從URL讀取的資料、解碼為文字的資料、以及分割為單詞的文字。所有這些單詞都放在set中。

物件:集合是一種物件,它支援取交和測試成員的操作。物件整合了資料和運算元據的邏輯,並以一種隱藏其複雜性的方式。物件是第二章的主要話題。

表示式

是一個複合表示式,計算出正序或倒序出現的“莎士比亞詞彙”集合。神祕的記號w[::-1]遍歷單詞中的每個字元,然而-1表明倒序遍歷(::表示第一個和最後一個單詞都使用預設值)。當你在互動式會話中輸入表示式時,Python會在隨後列印出它的值,就像上面那樣。

直譯器:計算複合表示式需要可預測的過程來精確執行直譯器的程式碼。執行這個過程,並計算複合表示式和語句的程式就叫直譯器。直譯器的設計與實現是第三章的主要話題。

與其它計算機程式相比,程式語言的直譯器通常比較獨特。Python在意圖上並沒有按照莎士比亞或者回文來設計,但是它極大的靈活性讓我們用極少的程式碼處理大量文字。

最後,我們會發現,所有這些核心概念都是緊密相關的:函式是物件,物件是函式,直譯器是二者的例項。然而,對這些概念,以及它們在程式碼組織中的作用的清晰理解,是掌握程式設計藝術的關鍵。

1.1.5 實踐指南

Python正在等待你的命令。你應當探索這門語言,即使你可能不知道完整的詞彙和結構。但是,要為錯誤做好準備。雖然計算機極其迅速和靈活,它們也十分古板。在史丹佛的導論課中,計算機的本性描述為

計算機的基本等式是:計算機 = 強大 + 笨拙

計算機非常強大,能夠迅速搜尋大量資料。計算機每秒可以執行數十億次操作,其中每個操作都非常簡單。

計算機也非常笨拙和脆弱。它們所做的操作十分古板、簡單和機械化。計算機缺少任何類似真實洞察力的事情…它並不像電影中的HAL 9000。如果不出意外,你不應被計算機嚇到,就像它擁有某種大腦一樣。它在背後非常機械化。

程式是一個人使用他的真實洞察力來構建出的一些實用的東西,它由這些簡單的小操作所組成。

—Francisco Cai & Nick Parlante, 史丹佛 CS101

在你實驗Python直譯器的時候,你會馬上意識到計算機的古板:即使最小的拼寫和格式修改都會導致非預期的輸出和錯誤。

學習解釋錯誤和診斷非預期錯誤的原因叫做除錯(debugging)。它的一些指導原則是:

  1. 逐步測試:每個寫好的程式都由小型的元件模組組成,這些元件可以獨立測試。儘快測試你寫好的任何東西來及早捕獲錯誤,並且從你的元件中獲得自信。
  2. 隔離錯誤:複雜程式的輸出、表示式、或語句中的錯誤,通常可以歸於特定的元件模組。當嘗試診斷問題時,在你能夠嘗試修正錯誤之前,一定要將它跟蹤到最小的程式碼片段。
  3. 檢查假設:直譯器將你的指令執行為文字 — 不多也不少。當一些程式碼不匹配程式設計師所相信的(或所假設的)行為,它們的輸出就會是非預期的。瞭解你的假設,之後專注於驗證你的假設是否整理來除錯。
  4. 詢問他人:你並不是一個人!如果你不理解某個錯誤資訊,可以詢問朋友、導師或者搜尋引擎。如果你隔離了一個錯誤,但是不知道如何改正,可以讓其它人來看一看。在小組問題解決中,會分享一大堆有價值的程式設計知識。

逐步測試、模組化設計、明確假設和團隊作業是貫穿這門課的主題。但願它們也能夠一直伴隨你的電腦科學生涯。

相關文章