本文是過去發表在雜誌上的文章,為了重新登在這裡,我作了一些編輯,不過因為是舊文,之中有些內容是已經過時了。類似的文章還有一些,我會慢慢地整理到這個 blog 上。
1 Python 是什麼?
各位好,今天我們要來介紹 Python 這一套功能強大、直譯式並且物件導向的程式語言。你或許聽過,或許沒聽過,但現在有機會來認識它了。
功能強大的直譯式程式語言不只有 Python,為什麼單單要介紹它呢?因為 Python:
容易撰寫。
Python 具有許多物件導向的特性,然而並不要求一定得用物件導向的方式撰寫。撇開物件導向的議題不談,Python 通常可以靠比較短的程式碼完成比較多的功能,或者可以寫得比較清楚。
功能強大。
Python 自 1990 年由 Guido van Rossum 在荷蘭的 CWI 開始發展以來,從 0.9 進步到今天的 2.4.2,不但累積了相當完整的標準程式庫 (模組),更有無以計數的非標準模組,而且絕大部分都是開放原始碼的。單以內建的模組來講,從簡單的數學運算、字串處理、網際網路協定連線、網際網路資料處理、各種壓縮格式,以及 POSIX 與主要作業系統的支援功能等等,含括的範圍非常地廣泛。
跨平台。
各種主要的作業系統都支援 Python。Python 程式常常不需要修改,便可以同時在 Linux 與 Windows 平台上執行,即使撰寫 GUI 程式 (透過 PyGTK, wxPython 等 binding) 也是一樣。所撰寫的 Python 程式透過標準的 distutils (模組) 進行包裝後,用標準的方式即可安裝於各種平台;在 Windows 下更可以自動產生方便的可執行 installer。
容易擴充。
Python 算是執行效率不錯的直譯式語言,但畢竟比不上 C 和 Fortran。然而只要我們想,大可以 C/C++ 或 Fortran 撰寫高效率的模組;這些模組的使用方式,與內建模組以及用 Python 撰寫的模組完全一樣。最好的是,撰寫的方法並不困難。
2 安裝 Python 執行環境
如果你使用 Linux,特別是 Debian GNU/Linux 的話,這個環境對 Python 是非常和善的,只要用 apt-get install python 即可安裝 Python 直譯器。若在安裝 Debian 的時候有選擇 task,那麼 Debian installer 可能已經幫你把 Python 裝好了。無論如何,安裝不費吹灰之力。
Debian 把 Python 直譯器拆成好幾個套件:python, python-doc, python-profiler 與 python-dev。非開發人員的系統上通常只會安裝 python 套件,它包含了直譯器程式與相關二進位程式庫;如果我們想寫 Python 程式的話 (這是你在看這篇文章的目的之一,不是嗎?),python-doc 與 python-profiler 也應該要安裝起來。python-dev 包含的則是用來以其它語言開發延伸模組用的部分。
雖然目前最新版的 Python 已是 2.4.2 了,但 Debian 預設的 Python 版本仍是 2.3.5。Python 2.4 作了許多增強,但 Python 2.3 的套件 (協力套件) 支援性還是比較廣泛的。如果你想使用 2.4 版的 Python (或是倒回去 2.2, 2.1 版),請 apt-get install python2.4 (可以把 2.4 改成 2.2, 2.1,以安裝相對的版本)。這些不同版本的 Python 能夠共存在 Debian 裡,有需要時可以手動叫用。在其它的 Linux distribution 上,使用預裝的 Python 即可。
如果你希望自己手動編譯 Python,請到下載頁[2]下載 source code distribution。熟練的程式員可能喜歡這樣作,然而當你有品質良好的 Debian 套件可以用的時候,需要自行編譯的機會就不是那麼多了。
Python 在 2.4 以後的版本加入了許多好用的語言功能與模組,在執行效率上也有所增進。如果你對新的 Generator Expressions [3]、Decorators [4] 與其它新增的功能[5]有興趣,非常推薦使用 Python 2.4。
3 Python 基本語法
我們要用幾個簡單的範例程式,介紹 Python 的語法特色。由於這麼作無法精確完整地描述 Python 的寫法,所以推薦你繼續 (依序) 閱讀 PingYeh 的 Python 教材 [7] (中文)、Python Online Tutorial [8],以及比較硬的 Python Language Reference [9];另外,Dive into Python [10] 也是一本可以在網路上免費下載的好書,值得參考。
3.1 開始撰寫
讓我們來寫 Python 程式吧!Python 程式通常會存成 .py 檔,在 Windows 下的 Python 安裝程式會自動把這種副檔名和 Python 直譯器程式關聯起來,所以在指令行介面 (cmd.exe) 下輸入 "blahblah.py" 這樣的字眼,就會執行這個程式。而在 Linux 或其它 Unix-like 的系統裡面,就要再打開該檔案的執行權限 (通常以 chmod a+x blahblah.py 進行)。不管你使用哪種系統,我們還是先來 hello.py 一下:
#!/usr/bin/env python print "Hello, world"
執行的結果是 (Linux 環境):
$ ./hello.py Hello, world
要讓 Python 程式在 Windows 下執行的關鍵是副檔名 .py,而要在 Linux 下執行的關鍵除了執行權限要設定之外,還有一個就是 hello.py 第一行的「標頭」。在 Linux 下所有像 Python 這類的指令稿,在檔案的最前頭都必須要指定所使用的直譯器;在這裡寫為 "#!/usr/bin/env python",表示使用系統路徑裡第一個找到的 python 直譯器 (你的系統裡可能裝了不止一個 Python 喔),也就是預設的直譯器。如果沒有這個「標頭」,Linux 就不知道它是個 Python 程式了。
Note
另一方面,在 Linux 下並不一定要把 Python 程式的副檔名取為 .py;事實上許多以 Python 指令稿撰寫的軟體都沒有副檔名,乍看之下和一般的程式沒什麼兩樣。舉個例子,你可以安裝一下 meld 這個 GUI 的 diff 工具,跑起來順得很;如果沒有特別提起,許多人也不會想到它完全是用 Python 寫的吧。
3.2 檔案處理與字串
再來一個讀取檔案的例子 fileproc.py:
#!/usr/bin/env python f = open( "/var/log/messages" ) lines = f.readlines() f.close() for line in lines: print line
從第 2 行開始,程式會先打開 /var/log/messages 這個檔案 (Linux 的標準紀錄檔之一),然後用檔案物件 (open 函式會傳回檔案物件,我們取名為 f) 的 readlines() 方法一次讀取所有的文字行,然後在第 4 行關閉檔案。接著是重要的迴圈敘述;lines 是用來存放所有文字行的列表,for line in lines 這個敘述的意思是「一次取 lines 列表中的一個項目,取名為 line」。在 for 迴圈敘述後加上冒號,換行然後「縮排」,同一段縮排的程式表示是一個區塊;我們這個 for 迴圈的區塊裡只包含了一行敘述,就是把 line 印到螢幕上。
/var/log/messages 檔裡的資料應該很多,你會看到一大堆字串跑過螢幕。這就表示程式執行成功了。在 Windows 下,請更換一下 open() 函式所打開的檔案,只要是純文字檔即可。
Note
Windows 和 Linux 用來分隔目錄的字元是不同的。在 Windows 下要用反斜線 (\) 而非斜線 (/) 來分隔目錄,不過因為 \ 符號在 Python 裡表示脫逸字元,所以在雙引號裡,你要用連續兩個的 \\ 才能表示一個反斜線。否則 Python 可能會和你抱怨找不到檔案。
Python 裡的字串可以用單引號 (') 或用雙引號 (") 包圍的文字來表示,效果一樣。我們接下來要說明 Python 字串處理能力,順便展示 Python 的互動式環境。在 Windows 下打開指令行介面 (cmd.exe),輸入 C:\Python23\python;在 Linux 下的終端機內直接輸入 python,都可以進入互動式環境:
$ python Python 2.3.5 (#2, Aug 30 2005, 15:50:26) [GCC 4.0.2 20050821 (prerelease) (Debian 4.0.1-6)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
在 Linux 下要跳出時是按 Ctrl-D,而在 Windows 下則是按 Ctrl-Z。通常 Python 互動式環境的提示符號是如上的 >>>。再來,試著輸入以下指令:
>>> print "a b c".split() ['a', 'b', 'c']
字串在 Python 裡也是一種物件,所以我們可以如上呼叫字串方法 split()。在不加參數的情況下,split() 方法會用字串裡的廣義空白 (包含空白、跳格與斷行等字元;連續的廣義空白字元視為單一的廣義空白) 來把字串斷成多個字串,並傳回包含這些字串的列表。我們可以指定列表元素的索引值來單獨存取這些字串:
>>> print 'this is an apple'.split()[2] an
這樣就取出了編號 2 的第三個單字 "an"。我們可以把這個技巧應用在之前讀取檔案的程式裡;只要知道檔案的格式,就能篩選出我們想要的字串資料。
如果我們想把字串寫進檔案,首先要用寫入模式來開啟新檔:
f = open( "newfilename.txt", 'w' )
再用檔案物件的 write() 方法來寫入字串:
f.write( "string data" )
最後不要忘了用 f.close() 關閉檔案。
3.3 使用模組
Python 模組 (module) 是一種非常方便的設計;適當地利用模組可以在不汙染命名空間的情況下獲得額外功能。模組的匯入是利用 import 敘述:
import sys
它匯入了最常用的 sys 內建模組。如果我們想處理指令行引數,就要靠 sys 模組裡的變數 argv:
#!/usr/bin/env python import sys print sys.argv
把這個程式存為 echoargs.py,然後執行:
$ ./echoargs.py arg1 arg2 ['./echoargs.py', 'arg1', 'arg2']
它把所有的指令行引數都印了出來,以列表的形式。sys.argv 這個變數實際上是個列表,它與 C 程式 main() 進入點函式的 argv 參數有異曲同工之妙,連名字都取作一樣;只是更為好用,因為 Python 的列表比 C 陣列自動化得太多,我們不必擔心列表項目的個數問題,Python 會幫我們處理好的。
Python 還有許多其它的模組,基本上都是以相同的方式匯入並使用的,請參閱線上手冊。
3.4 縮排、縮排、縮排
Python 程式語言的一個最大的特色就是以縮排定義程式結構。不像 C, C++, Java 等語言用括號定義程式區塊 (類別、函式、條件判斷和迴圈等),在 Python 裡,行首的「空白字元個數」 (即縮排) 就定義了區塊結構。許多會寫像
int main(){ int i; double d; d = 1.d0; i = 2; }
這種程式的人一開始會非常不習慣這種作法;但所有程式設計的書都會告訴你程式碼應該要排整齊,亂排只會增加往後維護的困難度而已。Python 強迫程式員把程式寫得漂亮,這不單簡化了往後的維護工作,更去掉了程式裡那些擾人的括號,對減少程式碼長度來說效果良好。
Note
適當地縮短程式碼的行數絕對是好事。一個函式能在一頁裡列完,就能比兩三頁長的函式更易讀易懂,也更不容易寫錯。
在 Python 裡,
print "Hi" print "hi"
是不合法的,要寫成
print "Hi" print "hi"
才可以。相對地,
if 1 == 1: print "1 == 1, of course"
是錯誤的寫法,要寫成像
if 1 == 1: print "1 == 1, of course"
這樣才對。
至於一次縮排要縮多少個字元,Python 並沒有進行限制,甚至不同的段落空白不一樣長也可以;只要同一個區塊的行首空白數相同即可。然而經驗告訴我們,第一,「絕對不要用跳格鍵」,如果你用 VIM 寫程式,可以用 :set et 打開跳格鍵的空白取代功能 (好一點的編輯器一定都有這種功能,你的編輯器沒有的話,可能該考慮換一個了);第二,縮排字元數要固定。Python 的爸爸 Guido van Rossum 喜歡用 4 個字元進行縮排,許多人都覺得這樣很好。
4 Python 的應用
本文對 Python 作了粗淺的介紹,其實還非常地殘缺不全。你可能仍然不太了解 Python,所以最後我們要用一點篇幅來看看目前 Python 這個語言究竟有用在哪些地方?看過以後,你或許會比較有繼續研究下去的動力。
- Zope 應用程式伺服器與相關系統。Zope 是一套以 Python 撰寫的高效率應用程式伺服器,主要用於網頁應用程式的開發;而在 Zope 之上則有 Plone 這套全功能的內容管理系統。Zope 與 Python 的發展息息相關,嶄新的 ZopeX3 與 Python 模組系統有相當優雅的結合,即使你對網頁應用程式沒興趣,其程式碼也非常值得參考。
- 科學計算。在要求效率的科學計算領域,Python 是強力工具。SciPy, Matplotlib, ScientificPython 等等都是專為科學計算設計的套件,而另有一些工具可以用來彌補身為描述式語言的 Python 在執行效率上先天弱勢的缺點,請參考 SciPy 網頁上的報告 [11],基本上可以讓以 Python 為主體的程式和純 C++ 程式的執行效率差距在 10% 以內。
- Web application。在 Python 上有許多以網頁應用為標的的計畫,在 Python wiki 上有好幾組列表 [12],光應用程式框架就有二十個左右,其中 Django 和 Turbogears 是近來討論最多的框架,值得注意。
- 圖形介面程式。以 Python 撰寫一般的圖形介面程式是相當理想的選擇。GTK、Qt 和 wxWidget 等常用的 GUI 框架都有 Python binding,程式員可以丟開複雜的 C/C++ 介面,把記憶體管理交給 Python,用最快的速度製作程式的雛形。若應用環境允許,直接以 Python 程式碼發行更是方便的選擇。
- 作業系統管理。談到作業系統管理很難不提到 Perl,Perl 一直以來都是 Unix-like 系統上的瑞士刀,而且是最高級的那一種。然而 Perl 程式設計的藝術性也造成了一些問題,Python 可能是更輕鬆的另一種選擇。在處理字串上,Perl 仍然勝過 Python 不少,但在字串處理不那麼吃動的系統上,譬如 Windows,配合 win32all 套件,Python 可能就比 Perl 更合適了。
5 參考資料
[1] | Python: http://www.python.org/ |
[2] | Python 下載頁: http://www.python.org/download/ |
[3] | PEP 289 Generator Expressions in Python 2.4: http://docs.python.org/whatsnew/node4.html |
[4] | PEP 318 Decorators for Functions and Methods in Python 2.4: http://docs.python.org/whatsnew/node6.html |
[5] | Python 2.4 新增項目: http://docs.python.org/whatsnew/whatsnew24.html |
[6] | PIL: http://www.pythonware.com/products/pil/ |
[7] | 葉平的 Python 教材: http://www.ossacc.org/Download/TM/OssaccTM/Python/ |
[8] | Python Tutorial: http://docs.python.org/tut/tut.html |
[9] | Python Language Reference: http://docs.python.org/ref/ref.html |
[10] | Dive into Python: http://diveintopython.org/ |
[11] | SciPy 的效能比較: http://www.scipy.org/documentation/weave/weaveperformance.html |
[12] | Python web programming: http://wiki.python.org/moin/WebProgramming |
- Previous: Mercurial 1.0 @2008/03/25
- Next: 晚了一步 @2008/04/08
Please send trackback to: http://blog.seety.org/everydaywork/2008/4/7/1007/trackback/.