顧曉東 付瑩 江蘇第二師范學院
高級腳本語言Python一直被認為是“終生受用的程序設計語言”,除了因為Python有非常完善的基礎代碼庫、易于理解和學習、研究人員更容易做快速原型,它還擁有大量的第三方庫。Python讓專業(yè)人員主要考慮解決問題的方法,而不用考慮實現(xiàn)方案所需的技術。很多“一小時學python”的實踐聲稱大多數(shù)沒有任何程序設計基礎的大一學生都可以在一小時內(nèi)理解Python設計方法并具備十幾行代碼的編寫能力[1]。然而筆者在教學過程中發(fā)現(xiàn),情況并非如此。以下筆者先羅列了python語言的優(yōu)缺點再以具體實例分析了python的優(yōu)弱點和一些教學細節(jié)。
Python語言的定位是“優(yōu)雅”、“明確”、“簡單”,其顯著的優(yōu)點有:(1)對初學python的人來說,python非常適合閱讀。python雖然是用c語言寫的,但是它擯棄了c語言中復雜的指針,簡化了語法。(2)Python是FLOSS(自由/開放源碼軟件)之一。簡單地說,閱讀者可以自由地發(fā)布這個軟件的拷貝、閱讀它的源代碼、對它做改動、把它的一部分用于新的自由軟件中。(3)Python可以被移植在許多平臺上。如果編程者小心地避免使用依賴于系統(tǒng)的特性,那么所有的Python程序無需修改就可以在下述任何平臺上運行。這些平臺包括Linux、Windows、FreeBSD、Macintosh、Solaris、OS/2、Amiga、AROS、AS/400、BeOS、OS/390、z/OS、Palm OS、QNX、VMS、Psion、Acom RISC OS、VxWorks、PlayStation、Sharp Zaurus、Windows CE甚至還有PocketPC、Symbian以及Google基于linux開發(fā)的Android平臺?。?)Python既支持面向過程的函數(shù)編程也支持面向?qū)ο蟮某橄缶幊獭T诿嫦蜻^程的語言中,程序是由過程或僅僅是可重用代碼的函數(shù)構建起來的。在面向?qū)ο蟮恼Z言中,程序是由數(shù)據(jù)和功能組合而成的對象構建起來的。與C++和Java相比,Python以一種非常強大又簡單的方式實現(xiàn)面向?qū)ο缶幊?。?)python擁有的大量第三方庫可以用來完成各種工作,包括正則表達式、文檔生成、單元測試、線程、數(shù)據(jù)庫、網(wǎng)頁瀏覽器、CGI、FTP、電子郵件、XML、XML-RPC、HTML、WAV文件、密碼系統(tǒng)、GUI(圖形用戶界面)、Tk和其他與系統(tǒng)有關的操作。除了標準庫以外,還有許多其他高質(zhì)量的庫,如wxPython、Twisted和Python圖像庫等等。
同時,Python的缺點有:(1)python的實現(xiàn)性能極低!大致和C相差五倍左右。如果是大規(guī)模計算,大致能差10倍以上。(2)python的底層設計相對混亂。(3)Python語言的自構建特性混亂。一般而言,高級語言都是使用C語言實現(xiàn)一個內(nèi)核,由內(nèi)核實現(xiàn)一些基礎操作,再由基礎操作實現(xiàn)更復雜的操作,各層的邊界非常清晰。而python中庫的相互依賴層級不清晰。(4)python的沙盒(sandbox)化難以保證本地效果/跨平臺/安全性。當我們要寫很多種程序時,python環(huán)境中的依賴勢必越來越多。有時還會導致沖突的出現(xiàn),python的沙盒環(huán)境VirtualEnv可以根據(jù)需要在一臺機器上創(chuàng)建多個獨立的Python虛擬運行環(huán)境,多個Python環(huán)境相互獨立,互不影響。事實上,python的沙盒難以保證本地效果/跨平臺/安全性。
由于python的底層設計相對混亂,初學者往往要花很長時間來研究以下程序:
其原因在于:python在運行時變量的作用域查找順序依次是:local(局部作用域),enclosing(函數(shù)范圍作用域),global(全局作用域),build-in(內(nèi)建對象作用域),簡稱LEGB(Local -Enclosed- Global - Built-in)規(guī)則。LEGB(Local -Enclosed - Global- Built-in)規(guī)則。程序在調(diào)用內(nèi)部函數(shù)inner_fun()時輸出3,返回主函數(shù)時,局部變量a被釋放,全局變量a依然為2。在C語言 中,變量名是內(nèi)存地址的別名,而在 Python 中,名字是一個字符串對象,它與它指向的對象構成一個{name : object}關聯(lián),Python 中name-object的關聯(lián)存儲在不同的作用域中,而各個不同的作用域是相互獨立的。
Type(name,bases,attrs) ,其中name為類名字符串,bases為父類元組,attrs為屬性字典。元類是生成類的類,比類更抽象。元類定義的是類的方法,類定義的是實例方法。(如圖1)。
圖1 python中的元類
對一般的程序員來說,這種用一個類生成另一個類的寫法相對難以理解。
相對于c語言的數(shù)組定義,python的列表無須預先分配大小,創(chuàng)建列表變量時不需要知道元素個數(shù),可以在使用中動態(tài)插入任何數(shù)量的元素,且列表中不同元素的類型可以相同也可以不同。列表的概念為程序編寫提供了很大的設計空間,同時也因為程序過于簡潔使學生并沒有理解程序的實質(zhì)意義,陷入能看“懂”卻不會編寫的狀態(tài)。以下是冒泡法的C程序和Python程序的比較。
可以看出,python程序異常簡潔,但理順算法的實現(xiàn)卻不容易,相比C程序缺少了數(shù)據(jù)元素的交換細節(jié)。
再以經(jīng)典的羊車門問題的python程序為例:有三扇關閉的門,一扇門后面停著汽車。其余門后是山羊,只有主持人知道每扇門后面是什么。參賽者可以選擇一扇門,在開啟它之前,主持人會開啟另外一扇門露出門后的山羊,然后允許參賽者更改自己的選擇。請問:參賽者更換選擇能否增加猜中汽車的機會?
圖2 羊車門問題的python程序
程序使用random庫生成隨機數(shù),但更改選擇相對不更改選擇的隨機數(shù)列表少了首次選擇的門和主持人打開的門。由以上程序也可以看出列表的概念使得python程序異常簡潔,常常學生覺得程序簡單,可上手編寫時卻無從下手。筆者在教學中常采用比較python程序和c程序的方式,使學生能進一步理解程序的細節(jié),取得了良好的教學效果。
Python是一種解釋型、面向?qū)ο?、動態(tài)數(shù)據(jù)類型的高級程序設計語言。筆者在教學中發(fā)現(xiàn)雖然其適合閱讀但難以編寫。本文以具體實例分析了python的優(yōu)弱點和教學中的一些細節(jié),對python的教學有一定的指導意義。