1. 程式人生 > >Python程式設計課程教學方法與教學重點探討

Python程式設計課程教學方法與教學重點探討

Python語言是由荷蘭人Guido van Rossum於1989年底開始設計1991年正式發行的,推出不久就迅速得到了各行業人士的青睞。Python是完全跨平臺的語言,程式碼具有非常強的可移植性,幾乎不需要改動即可運行於Unix、Linux、Solaris、Windows、Mac OS、Pocket PC、Symbian、Android等不同平臺。更重要的是,Python可以和C/C++/C#、Java等主流語言完美地結合到一起,充分發揮每種語言的優勢。Python易學易用且功能強大,目前已經滲透到統計分析、大資料處理、移動終端應用開發、科學計算視覺化、逆向工程與軟體分析、圖形影象處理、人工智慧、遊戲設計與策劃、

網路程式設計、自動運維等幾乎所有專業和領域。著名搜尋引擎google的核心程式碼使用Python實現,迪斯尼公司的動畫製作與生成採用Python實現,大部分Unix和Linux都內建了Python環境支援,豆瓣網使用Python作為主體開發語言進行網站架構和有關應用的設計與開發,網易大量網路遊戲的伺服器端程式碼超過70%採用Python進行設計與開發,易度的PaaA企業應用雲端開發平臺和百度雲端計算平臺BAE也都大量採用了Python語言,美國宇航局使用Python實現了CAD/CAE/PDM庫及模型管理系統,Yahoo使用Python建立全球範圍的站點群,微軟整合開發環境Visual Studio 2015開始預設支援Python語言而不需要像之前的版本一樣再單獨安裝
PTVS和IronPython外掛,類似的案例數不勝數[1]

Python語言連續多年在TIOBE程式語言排行榜排名7、8位,2011年1月被TIOBE網站評為2010年度語言,在2014年12月IEEE Spectrum的程式語言排行榜中更是取得了第5名的好位次。目前Python已經成為卡耐基梅隆大學、麻省理工學院、加州大學伯克利分校、哈佛大學等國外很多著名大學計算機專業或非計算機專業的程式設計教學語言,國內如安徽大學、西安工業大學、山東師範大學、山東工商學院、新疆農業大學等校也針對部分專業開設了Python程式設計課程。

本文以Python 3.5為例,對Python程式設計模式和Python

程式設計課程的教學重點進行剖析,同時簡要比較和分析不同領域的主流Python擴充套件庫。

Python程式設計模式與教學方法

Python是一門免費、開源的跨平臺高階動態程式語言,支援指令式程式設計、函數語言程式設計,完全支援面向物件程式設計,語法簡潔清晰、優雅,程式碼可讀性強,並且擁有大量功能豐富而強大的標準庫和擴充套件庫,可以幫助各領域的工程師、科研人員或策劃師甚至管理人員快速實現和驗證自己的思路與創意。Python程式設計模式非常符合人類的思維習慣,Python使用者可以把主要精力放在業務邏輯的設計與實現上,大幅度縮短了開發週期,在開發速度和執行速度之間達到了完美的平衡,其精妙之處令人擊節讚歎[2,3]

Python官方網站上在非常醒目的位置有一句話“Python is a programming language that lets you work quickly and integrate systems more effectively”,在The Zen of Python中也反覆提到類似的話,例如“Explicit is better than implicit”、“Simple is better than complex”、“Flat is better than nested”、“Sparse is better than dense”、“Readability counts”,指出了Python語言的本質和核心所在。作為Python使用者,儘量嘗試從最自然、最簡潔的角度出發去思考和解決問題,這樣才能寫出更加優雅、更加Pythonic的程式碼。在講授Python程式設計課程時,建議採用邊講邊練、學生分組合作的教學模式,精心設計一些案例帶領學生一起完成並做好嚴格的過程控制與管理,同時經常鼓勵和引導學生去想“還有沒有更簡潔更快速更直接更好的方法?”類似的問題,激發學生的潛能,也充分挖掘Python語言的潛能。

大部分講授Python的老師都有其他語言的程式設計經驗,聽課的學生也很可能接觸過其他程式語言。不少人認為Python不過是眾多程式語言的其中一種而已,只要熟悉一下語法就可以掌握和應用,這樣的想法是非常錯誤和危險的。在講授、學習和應用Python時,切記不要把其他語言的程式設計習慣和風格帶到Python中來使用其他語言尤其是C語言的思路去編寫Python程式,那會使得程式碼變得非常冗、繁瑣、可讀性差並且難以維護,浪費大量的寶貴時間,無法發揮Python的優勢,甚至有可能寫出看似正確實則錯誤的程式碼

2 Python基礎知識教學重點

2.1 程式碼規範

Python嚴格使用縮排來體現程式碼的邏輯關係,並且建議在運算子兩側各增加一個空格在不同的函式定義、類定義和不同功能程式碼之間增加一個空行,程式碼佈局和邏輯非常清晰具有很強的可讀性。在編寫選擇結構、迴圈結構以及定義函式和類時,一定要嚴格按照預期的邏輯關係對程式碼進行正確的縮排。在類定義、函式定義以及關鍵程式碼處,應使用簡單的註釋來說明邏輯關係和程式碼功能。另外,還有些習慣也是應該在學習Python之就應該養成的,例如每個import語句只匯入一個模組,儘量避免使用類似於from numpy import *之類的寫法,等等。從編寫第一段Python程式碼開始,就要讓學生養成良好的習慣[2,4]

2.2 關鍵字、變數、運算子與表示式

在任何程式語言中,關鍵字、變數、運算子、表示式都是最基本和最重要的內容,Python也不例外。在Python中,可以使用print(keyword.kwlist)語句檢視所有關鍵字列表,並且不允許使用關鍵字作為變數、函式或類名。Python採用的是基於值的自動記憶體管理模式,變數不直接儲存值,而是儲存值的引用,這使得Python變數的使用非常靈活方便,例如在列表或元組等序列中可以同時儲存不同型別的資料。在Python中,變數不需要提前宣告,使用結束後也不需要刻意考慮變數的釋放,同時還支援動態改變變數型別。下面的程式碼首先建立了整型變數x並賦值為3,然後先後將實數和字串以及列表賦值給變數x,動態改變了變數的型別[2,3,5-8]

>>> x = 3

>>> type(x)

<class 'int'>

>>> x = 3.5

>>> type(x)

<class 'float'>

>>> x = 'SDIBT'

>>> type(x)

<class 'str'>

>>> x = [1, 2, "3", [4, 5]]

>>> type(x)

<class 'list'>

Python運算子型別較多,除了算術運算子、關係運算符、邏輯運算子等常規運算子之外,還有成員測試運算子in、同一性測試運算子is,,Python 3.5引入矩陣運算子@。Python中很多運算子具有多重含義,例如+運算子既可以用來實現整數、實數的加法運算,也可以實現字串、元組、列表的連線;|運算子既可以用於數字的位或運算,可以實現集合的並集運算,等等。Python關係運算符不僅支援整數、實數、字串、列表、元組的大小比較,還可以用來判斷集合之間的包含關係,並且支援連續使用。下面的程式碼演示了部分運算子的用法。

>>> 3+5

8

>>> 'Hello '+'world'

'Hello world'

>>> (3,5)+(7,)

(3, 5, 7)

>>> 3 in _

True

>>> 3 | 5

7

>>> {1, 3, 5} | {7}

{1, 3, 5, 7}

>>> {1, 3, 5, 7} & {7}

{7}

>>> 5 & 3

1

>>> 1 < 20 > 5

True

2.3 Python序列

Python不僅提供了整數、實數、字串等常見資料型別,還內建了列表、元組、字典、集合等功能強大的序列型別,同時range物件、reversed物件、map物件、檔案物件以及其他可迭代物件也支援Python序列類似操作。序列可以說是Python最重要的一部分內容,也是實現業務邏輯的重要途徑,這部分內容一定要精講多練。

列表、元組、字串等有序序列的雙向索引大幅度提高了開發效率,單引號、雙引號、三引號等靈活的字串界定符和原始字串可以讓使用者寫出可讀性更強的字串而不需要藉助於轉義字元,正則表示式模組re更是把字串處理功能發揮到了極致列表推導式、生成器推導式、字典推導式和集合推導式支援使用簡潔的形式實現某些複雜功能,切片可以非常靈活地訪問和修改列表元素,序列解包廣泛應用於賦值、函式引數傳遞或列舉序列元素,這些都應該作為教學重點內容。下面的程式碼演示了Python序列的強大功能。

>>> range(20)[::2]

range(0, 20, 2)

>>> list(_)

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

>>> 'SDIBT'[-1]

'T'

>>> ''.join(map(chr,[random.randint(65,90) for i in range(20)]))

'EPYORZFZEDYAFVAJVFSC'

>>> x = list(range(10))

>>> x

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> x[::2] = [0]*(len(x)//2)

>>> x

[0, 1, 0, 3, 0, 5, 0, 7, 0, 9]

>>> x = [1, 2, 3]

>>> y = ['a', 'b', 'c']

>>> for item1, item2 in zip(x,y):

print(item1, item2)

1 a

2 b

3 c

2.4 帶有else的迴圈結構和異常處理結構

在Python中,for迴圈while迴圈異常處理結構可以帶有else子句。對於迴圈結構而言,當迴圈條件不成立時執行else中的程式碼,如果是執行了break語句跳出迴圈則不執行else中的程式碼。對於異常處理結構而言,如果try中的程式碼沒有引發異常則執行else中的程式碼。帶有else子句的迴圈結構和異常處理結構更符合人類的思維方式,可讀性較強,同時也減少了程式碼量,是應該熟練掌握和運用的。

2.5 Python內建函式和標準庫

Python提供了大量內建物件和內建函式以及標準庫,這些程式碼都是經過反覆推敲和優化的,執行穩定且具有非常高的效率,在編寫程式碼時應優先考慮使用。教學中應培養學生經常瀏覽Python幫助文件的習慣,熟悉Python提供的內建物件和標準庫功能,而不是遇到什麼問題都首先想到自己寫程式碼實現全部功能,這樣才能獲得高的開發效率。同時,為培養學生自學能力和獲取新知識的能力,應要求熟練使用dir()函式檢視模組中物件列表以及使用help()函式檢視物件使用幫助。下面通過幾個例子說明Python內建函式和標準庫的強大功能。

雖然列表物件已經提供了原地排序方法sort(),內建函式sorted()則提供了更強大的功能,可以實現列表、元組、字典以及range和其他可迭代物件的複雜排序。例如下面的程式碼[2]

>>> import random

>>> x = [[random.randint(1, 100) for j in range(3)] for i in range(3)]

>>> x

[[100, 59, 31], [52, 98, 61], [32, 49, 95]]

>>> sorted(x, key=lambda x: x[1]) #按子列表第1個元素進行升序排序

[[32, 49, 95], [100, 59, 31], [52, 98, 61]]

>>> sorted(x, key=lambda x: x[2], reverse=True) #按子列表第2個元素降序排序

[[32, 49, 95], [52, 98, 61], [100, 59, 31]]

>>> x.sort()  #預設按子列表第0個元素升序排序

>>> x

[[32, 49, 95], [52, 98, 61], [100, 59, 31]]

>>> x.sort(key=lambda x:x[1]) #按子列表第1個元素升序排序

>>> x

[[32, 49, 95], [100, 59, 31], [52, 98, 61]]

>>> import operator

>>> gameresult = [{'name':'Bob', 'wins':10, 'losses':3, 'rating':75.0},              {'name':'David', 'wins':3, 'losses':5, 'rating':57.0},              {'name':'Carol', 'wins':4, 'losses':5, 'rating':57.0},              {'name':'Patty', 'wins':9, 'losses':3, 'rating':72.8}]

>>> sorted(gameresult, key=operator.itemgetter('wins', 'name'))

[{'name': 'David', 'wins': 3, 'losses': 5, 'rating': 57.0}, {'name': 'Carol', 'wins': 4, 'losses': 5, 'rating': 57.0}, {'name': 'Patty', 'wins': 9, 'losses': 3, 'rating': 72.8}, {'name': 'Bob', 'wins': 10, 'losses': 3, 'rating': 75.0}]

計算兩個整數的最大公約數,接觸過其他語言的人可能會首先想到按照歐幾里得演算法編寫下面的程式碼:

>>> def gcd(m, n):

    if m>n:

        m, n = n, m

    while m != 0:

        r = n % m

        n = m

        m = r

return n 

然而,Python標準庫fractions已經提供了用於計算最大公約數的方法gcd(),直接呼叫即可。例如:

>>> import fractions

>>> fractions.gcd(40, 32)

8

>>> fractions.gcd(64, 32)

32

再例如,如果需要求解若干數的中位數,需要先對所有資料進行排序然後返回中間位置上的數,如果自己編寫程式碼求解中位數會耗費一定的時間,而Python標準庫statistics已經提供了median()函式來解決這一問題。例如:

>>> import random

>>> x = list(range(1,10))

>>> x

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> random.shuffle(x)

>>> x

[2, 4, 5, 8, 6, 1, 3, 7, 9]

>>> import statistics

>>> statistics.median(x)

5

類似的情況在Python中數不勝數,標準庫itertools提供了用於計算排列的函式permutations()和計算組合的函式combinations()以及用於迴圈遍歷指定序列的函式cycle(),標準庫random提供了用於從指定序列中隨機選擇k個元素的函式sample()和將列表資料隨機打亂順序的函式shuffle(),標準庫datetime提供了timedelta物件可以很方便計算指定年、月、日、時、分、秒之前或之後的日期時間以及返回結果包含了“今天是今年第幾天”、“今天是本週第幾天”等答案的timetuple()函式,等等。

2.6 Lambda表示式

lambda表示式可以用來宣告匿名函式或具名函式,尤其適合臨時需要某個功能而又不值得定義函式的場合lambda表示式只包含一個表示式,該表示式的計算結果可以看做函式的返回值。Python中很多函式和方法都支援lambda表示式作為引數,本文前面示例中已經展示lambda表示式的強大功能,再例如下面的程式碼:

>>> f = lambda x: x**3 + x**2 + 1

>>> f(3)

37

>>> f(2)

13

>>> import itertools

>>> x = [1, 2, 3, 4, 5]

>>> list(itertools.accumulate(x, lambda a,b: a*b))

[1, 2, 6, 24, 120]

>>> list(itertools.accumulate(x, lambda a,b: b-a))

[1, 1, 2, 2, 3]

>>> import functools

>>> functools.reduce(lambda a,b:b-a,range(1,10))

5

>>> functools.reduce(lambda a,b:a+b,range(10))

45

Python標準庫和擴充套件庫簡介

Python擁有大量涉及幾乎所有領域的標準庫和擴充套件庫,並且絕大部分擴充套件庫都支援使用pip工具進行安裝和管理。需要說明的是,不論針對哪個領域的應用開發,也不論選擇哪個標準庫或擴充套件庫,Python運算子、序列、各種推導式、程式控制結構、異常處理結構、檔案操作等基本知識都是非常重要的,只有完全理解和熟練掌握這些Python基礎知識才能更有效地運用各種擴充套件庫。另外,在每個行業和領域都有很多擴充套件庫可供選擇很多擴充套件庫各有特點,互相之間並沒有嚴格的優劣之分,選擇使用哪個擴充套件庫更多的是個人喜好和習慣。本文嘗試對部分領域的主流Python擴充套件庫進行簡介紹,在教學過程中可根據具體的學生專業進行適當選取。

3.1 GUI程式設計

在GUI程式設計方面,主流的有Tkinter、wxPython、PyQt、PyGTK、PySideAutoPy等模組。其中Tkinter是Python標準庫,可在Python所有版本中直接使用。wxPython是功能強大的平臺GUI擴充套件庫,遺憾的是目前最高只支援Python 2.7,近幾年更新有點緩慢。儘管Python的有關GUI庫已經比較成熟,但使用純Python編寫應用程式介面的效率仍然相對較低。可以考慮和其他語言結合,例如使用C#或Java的整合開發環境來搭建應用程式介面,而使用Python來實現業務邏輯,充分發揮不同語言的優勢[3]

3.2 網路程式設計

除了socket、urllib、cookielib、httplibftplib、email、smtp、html、json等適用於不同目的的網路程式設計標準庫之外,還有Django、Flask、webpy、Zope2、Pyramid、web2py、Bottle、TornadoGenshi等支援Python網站開發框架和擴充套件庫。也可以把Python語言直接嵌入asp檔案來實現特定功能,IIS以及Apache支援直接使用純Python開發和執行網站系統。Scrapy作為螢幕抓取和Web抓取框架,也得到了廣泛的應用[3]

3.3 大資料處理

MapReduce、Hadoop、Spark是目前比較主流的大資料處理平臺和框架,都可以和Python語言完美結合。DPark是Spark的Python實現,是一個Python實現的分散式計算框架,可以非常方便地實現大規模資料處理和迭代計算。作為高效能資料處理擴充套件包,pandas近幾年也表現出了足夠強大的功能[3]

3.4 系統程式設計與多語言混合程式設計

大多數版本的Unix和Linux發行版本都集成了Python支援,os、sys、platform等標準庫中含有大量的與作業系統程式設計有關的方法和類。pywin32擴充套件庫提供了win32api、win32con、win32process、win32event、win32gui等模組,支援Python對Windows幾乎所有底層功能的訪問和呼叫。擴充套件庫wmi使得Python可以訪問Windows系統中硬碟分割槽與使用情況,記憶體大小,CPU型號,當前執行的程序,自啟動程式及位置,系統版本等資訊。Python標準庫_winreg提供了Windows登錄檔程式設計的有關介面。跨平臺擴充套件庫psutil支援Python對CPU資訊、開機資訊、當前使用者、磁碟資訊、記憶體資訊甚至網路流量和收發包情況的檢視和分析。

cytpes標準庫支援在Python中呼叫動態連結庫或共享庫中的函式,Boost.Python擴充套件庫在C++和Python之間實現了完美的互操作性,利用Cffi擴充套件庫可以在Python中呼叫C語言程式碼,利用Cython可以編寫Python的C擴充套件,IronPython外掛允許在C#中直接嵌入Python程式碼或者呼叫外部Python程式檔案中的程式碼,Jpype使得Python可以擁有Java類庫的訪問權。JPython 是 Python 語言的純Java實現,可以將Python原始碼編譯成Java位元組碼並在任何Java虛擬機器上執行,是Python與Java的完美整合[3]

3.5 執行緒程式設計與程序程式設計

Python標準庫threading是高層執行緒程式設計介面,提供了大量的方法和類支援多執行緒程式設計,包括執行緒的建立、執行與狀態控制以及執行緒同步操作,極大地方便了使用者。標準庫queue實現了多生產者-消費者佇列,非常適合在多個執行緒之間進行資訊交換的場合。標準庫multiprocessing提供了大量用於程序程式設計的類和方法。另外,pywin32擴充套件庫中的win32process也使得Python可以很方便地建立和控制程序,psutil擴充套件庫支援對程序、執行緒等資訊的訪問和一定程度的控制[3]

3.6 資料庫程式設計

標準庫sqlite3和擴充套件庫APSW支援python對內建資料庫SQLite的操作,SQLiteManager、SQLite Database Browser等工具支援SQLite資料庫的視覺化操作。Python可