The Old Blog Archive (Traditional Chinese), 2004-2009

學 Python: 兼談成人的語言習得

代替一篇欠一位朋友很久的文章。

曾經有位朋友問我當初是怎麼把 [C, C++, Ruby] 等語言學起來的,但是這種事就跟問我當初是怎麼回會腳踏車或是學會騎機車一樣,為已經模糊的記憶加油添醋的成份太多了。

最近倒是因為有個新的工作項目,雖然屬於熟悉的領域,但是很多相關的工具都還沒準備好。這似乎是個學新語言的好機會。於是想說來學 Python。

幾年前,我快退伍的時候,當時跟一位 PHP 屬於神的等級的學弟請教,如果這時代要寫程式,應該學哪些東西。在許多當時聽來相當陌生的名詞當中,Python 是其中一項。但我後來卻去學了 Ruby ,而且一直沒有動機學 Python ,因為:

  1. Python 跟 Ruby 同質性太高。至少對我來說他們都想解決同樣的問題
  2. Ruby 的 OO 比較對我的胃口(Smalltalk 系、與 ObjC 有表親關係)
  3. Ruby on Rails

不過因為新的工作內容,需要找一個參與各方都會的語言來做為工具開發用,突然讓 Python 變成了一種必要(我是唯一在工作開始前還沒有真正接觸過 Python 的人)。

目前採用的方法、進度跟心得是這樣的。

我沒有找書來看。唯一憑藉的是 Python 官方網站上的文件。這其實還蠻危險的,因為官方網站的文件範例有點稀少(好比說在講解基本型別時,很多細微之處沒有舉很多例子)。與此相關的是 Python 3 與 Python 2 有很大的差別,問題是 Python 3 網站上的文件沒有適時標出問題所在。好比說,所有 Python 2 教材裡關於 map(lambda x : x * 2, (1, 2, 3)) 的例子到 Python 3 上面執行結果絕對不是教材說的那樣。

過去學其他程式語言,大體上最重要的幾個一定要知道的東西,目前也都過了一遍。一般說來一個程式語言最重要的資料型別是字串(這個真的在語言教學中被大大低估),尤其是 Unicode 的問題,任何在這個年代撰寫程式的人都有機會碰到。然後就是控制結構,知道迴圈跟條件分支怎麼寫。再來就是語言特性了,好比說 Python 就是 tuple/list 的特性、怎麼樣使用 map-reduce 等操作(後者在 Ruby 有個非常不像話的名字叫做 inject …)。不過我還沒碰觸到 Python 的 OO。

知道了控制結構跟基本型別的操作,接下來就是 stdio、檔案開啟、取得系統物件(例如像 sys.stderr, sys.argv 這類每種語言教法跟意義稍稍有點不一樣的東西),然後就是看 library reference 找自己需要的程式庫來完成手上的工作。粗淺的心得:SQLite 內建支援真不錯。Regex 似乎沒有 Ruby 方便(但是看來沒有什麼語言 regex 能比 Perl 方便……)

我跟朋友們說,其實成人學語言是相當尷尬的。一方面,你不太需要其他形式上的語言知識(你不再需要知道什麼是名詞、動詞;你不再需要知道什麼是浮點數、Unicode字串);另一方面,你卻也失去了從頭學語言的緩慢樂趣。尤其如果是為了完成工作的需要而學語言,慢慢嘗試探索、從笨拙的風格慢慢學習精簡、符合「成語」(idiom)的用法,這些都變成了一種時間的奢侈。

然後可以想見的是,這樣學語言,一定就會在某些幽微之處撞牆,而且死得很難看。君不見大家都說直接用 printf 寫 SQL statement 有多危險,但是你需要某種緩慢的閱讀速度,才會了解問題的根源跟解法。泰西諺語所謂:A little knowledge is a dangerous thing.

也就是說呢,我以前一直在尋找好比說「給 C++ 程式設計者的 ObjC 快速轉換入門」或是「給 C 語言程式設計者的 PHP 快速入門」這種可以只要拿著小抄一一對映過去就的指南,其實是不存在的。或者說,天底下沒有這麼便宜的事情。所有語言的背後或許全部都是共通的(這是很重要的假說),但是至少人間世的語言間(包括了程式語言)沒有存在完美的、唯一的一對一映射。

另一個困難在於,即使很快地克服了語言外貌所造成的障礙(熟悉了語言的文法),但是「習慣用法」(convention)才是最困難的,而那完完全全是時間的產物。Convention 除了包含「大家都習慣怎麼說/解決這個問題」外,還包括了「有那些不具文的、遇到了就要閃躲的坑洞」,更上一層甚至還包括了「直覺上就應該採取的路徑」或「直覺上就知道這是不可行的路徑」這種東西。

當然,最終來說,成人語言學習還是要回到任何語言學教科書開頭就會教你(而很多論辯語言的人都從沒搞懂)的兩大基本不同概念:能力(competence)與表現(performance)。你只要能用一種語言來從事活動(例如:閱讀別人的 code、靠著 copy-and-paste 解決問題),都可以說是具有一種語言的能力。但是你說得怎麼樣、寫得怎麼樣,上不上得了檯面,則是有可以評量的標準。其實,自知之明(know thyself!)講的也就是這麼回事:知道自己有能力並不代表能夠有好表現,你得惦惦自己有多少斤兩,有多少「才調」(tsâi-tiāu)。具體來說,會了英文不代表寫出來的東西不會被 native speaker 拿去投稿 engrish.com,「知道」什麼是 SQL 跟怎麼樣寫出不會被人 inject (此處 inject 不是 Ruby 那個 inject)的 SQL 操作也是天差地遠兩回事。

這當然跟自己的目標很有關係。如果你的目標不是「我要精通 x 語言」且沒有付出相對應代價、通過相對應考驗(這也仍然是兩回事,付出過苦工,跟上不上得了檯面沒有必然關係),但是卻又有著工作上的責任背負在身,此時最好還是遵循這個簡單的指導原則。這是一句鄉民用語,謂:「閃開,讓專業的來」。

至於我呢,在達成了內部工作需要的目標後,或許還是應該真的找一本好的書來讀,然後尋找其他用得上新學語言的場合來精進。如果有時間的話──因為忙碌而造成沒有辦法緩慢下來,以及因為有了既成的知識而再也無法像初心者一樣純真地看待任何幽微的細節,這兩者或許是成人語言習得 (language acquisition) 的萬惡之源。

11 Responses to “學 Python: 兼談成人的語言習得”

  1. on 25 Feb 2009 at 10:11ljmid

    嘩! 我還沒碰過 Python 3 …
    Python 2 的各個版本間也有細微的差距喲! (差在哪就不獻醜了,這邊高手雲集)
    老實說,線上的手冊就已經夠了。我買了 O’Reilly 的 Programming Python 發現一點用都沒有.
    或許是我討厭書?XD

  2. on 25 Feb 2009 at 10:16ljmid

    BTW, 如果你找到 「給 C++ 程式設計者的 ObjC 快速轉換入門」 能不能也給我一份 :D
    如果世界上真有這東西的話…

  3. on 25 Feb 2009 at 11:04vincicat

    我一直覺得學程式語言從書出發會輕鬆一點

    如果說書, O’Reilly的learning XXX是很好的入門書, 可以打好基礎之餘又免了不少坑 (不過learning python那本最新版厚的好嚇人)
    學convention的話, O’Reilly cookbook系列也提供很好的practices/solution

    不過有書還得要實作才可以體會書中理論, 讓自己記住那才是真的學到

    p.s.1 Perl我覺得很大程度是靠regex在撐
    p.s.2 我不是O’Reilly的Sale XDD

  4. on 26 Feb 2009 at 03:21yungyuc

    Python 3 真是沒什麼用呢

  5. on 26 Feb 2009 at 08:26Cornelius

    我並不覺得 perl 很大的程度是靠 regex 在撐,我不會用 “撐” 這個字眼。

  6. on 26 Feb 2009 at 17:57Sam

    python3 和 python2之間已經沒有相容性, 所以2的執行狀況可想而知和3會差異頗大, 但是週邊也不太可能那麼快支援3, 所以到底會怎麼樣還要一段時間看看, 畢竟python開發者的影響力不足以讓Google等公司重新改寫服務, 而是靠著他們沾光

  7. on 05 Mar 2009 at 11:05closer

    最近也開始在工作上利用 Python 做些事情。
    主要是用來過濾 header files,自動產生一些比較適合人類閱讀的文件。
    也許是我很少接觸這種 dynamic language 的關係吧,
    我對「動態輸入程式碼」還有它的字串處理留下了很深刻的印象。
    (雖然要把 C variants 的字串處理能力比下去是件輕而易舉的事情)

    對於在工作上的應用來說,我學習新語言的重點只在怎麼完成手上的任務。
    就拿 Python 來說,我到目前為主都只把它當成 script language 用,
    到現在連 function 都沒寫過,遑論 classes。
    But so what?
    能捉老鼠的就是好貓。

    所以語言內建的功能和函式庫是否好用就很重要了。
    就我學 Python 的例子來說,我大部份的時間是在學 list 怎麼用、以及在手冊裡尋找和字串和檔案處理相關的函式庫。
    然後反覆嚐試各項功能,直到程式運作正常。

    然後,如果這個語言不是主要求生技能,其實學習就告一段落了。
    因為這幾年寫程式的經驗告訴我,函式庫的功能都差不多。
    頂多再快速瀏覽一下函式庫,在心裡有個底,等到下次需要的時候再查就可以了。

    然後以後有人問:「你會寫 Python 嗎?」,
    就可以很瀟灑地回答他:

    「略懂。」

  8. on 05 Mar 2009 at 14:13pyname

    I use python for many years, even to earn a living with it. I found there is still many things to learn, everyday, I don’t understand why people think it is very easy here, even for those ‘連 function 都沒寫過,遑論 classes。’. …

  9. on 05 Mar 2009 at 20:23closer

    Hi pyname,

    首先,我並沒有 “Python 是很簡單的語言” 這樣的意思。
    若是前面留言中那句戲謔的「略懂」冒犯了您,我向您道歉。
    要完全把一個語言學到透徹的確是很難的。
    扣掉在學校的時間,我靠 C/C++ 吃飯也有七、八年了;但我仍不時接觸到我沒見過的技巧,甚至是沒看過的語法。

    我想要強調的重點是:了解語言的長處以及它能做到的事,比徹頭徹尾了解這個語言重要——至少對於我們這種偶爾才會用到這種語言的人來說是這個樣子。

    也許我很現實吧!但我認為語言是工具,只要能達到目的就可以了。
    今天我把 Python 當 batch file 用,是因為用這種方法就可以達到我的目的。
    但我知道 Python 有 function、有 OO。
    等到哪天我做比較複雜的事情,我認為 function、class 對這個程式有利,我自然會去翻手冊。

    若是工作性質有變,要我天天寫 Python,我自然會熟練這些語法。
    若是哪天我要改用別的語言,我應該也會用類似的方法儘快學會夠用的技巧,完成我的工作。
    (好吧!我不會 functional programming,所以你要我用 lisp or erlang 的話我就不行了)

    觀念比較重要,語言只是工具。

  10. on 07 Mar 2009 at 16:05pingooo

    歡迎來到 Python 的世界!

    Python 的一個好處其實已經被大家點出來了:你不需要學太多,就能解決不少問題。另一個好處是,六個月後回來讀,多半還讀得懂。這兩個是 Python “easy” 名譽的來源之二。

    @pyname: 當然,Python 也可以搞得很難,如 metaclasses,但大部分的程式不需要用到。

    我真的覺得 @closer 說他自己「略懂 Python」沒什麼錯,因為他已經能用 Python 解決問題了。

  11. on 18 Mar 2009 at 22:51pyname

    open your mind, you may see how wonderful the world is.

    get to the basics, you may see the details behind that,

    you may not know the following header lines in python 2.x
    scripts is a valid utf-8 script.

    #! /usr/bin/python
    #ma ma pa pa haha coding=utf8

    print ‘繁體’

    That could not be more basics, but you may not know the reason why