2018.11.21更新:博碩出版社年末活動,推出本書的
暢銷回饋版。
2018.08.05更新:出版後過了三年,達到
十一刷。歡迎任何改版建議、意見。
2017.11.11更新:出版後過了兩年六個月,居然達到
九刷。若有任何改版建議,還請留言。
2016.09.20更新:本書的投影片,
可到此下載。
嗨,各位好,我寫了一本Python程式語言的入門書,還請多多指教。
書名:
Python程式設計入門
作者:我
出版社:博碩文化(
書號PG21421)
出版日期:2015年3月29日
頁數:544頁
ISBN:978-986-434-005-7
自從1980年代末以來,Python程式語言經過二十多年的耕耘,蓬勃發展,已成為世界當紅的主流開發語言之一,不論是開放原始碼界和商業公司,採用Python來開發軟體專案的例子比比皆是,更有許多成功的案例,而且不論是哪個領域,諸如網站開發、機器人控制、影像辨識、數學運算等,都可見其身影,足可知Python擁有非比尋常的的彈性與能力。
回想起過去的年代,當作者還是莘莘學子之時,學校開設的課程大都為C/C++/Java等語言,而在更早之前,作者的老師們學習的第一支程式語言,多半是Basic或Pascal,時至今日,許多學校與程式設計課程紛紛轉而使用Python作為教學語言,不僅是因為其語法簡潔易懂,適合作為初學者走入程式世界的第一支語言,也因為Python擁有豐富的功能與特色,即便將來欲走向其他領域或某特定的範疇,也都能使用Python,不必耗費時間學習另一支語言。
這是一本Python程式語言的入門書,將會詳細介紹Python的語法和語意,此部份屬於基本功夫,就好像學習英語時,需要學習單字、詞性、時態、文法等等,然後加以運用依據適當的結構寫出句子,也就是撰寫程式;但光如此並不足夠,我們還會介紹程式設計的各種概念,諸如函式、遞迴、閉包、物件等,並且會解說程式執行的抽象模型,透過該模型,思考寫下來的程式碼(死的)在執行時的動態交互作用(活的),如此一來,方能通透明白。
Python目前分為2.x版與3.x版兩個系列,彼此並非完全相容,換句話說,某些2.x版舊程式無法給3.x版執行,反之亦然;雖說3.x版較新較先進,但仍有很多人使用2.x版,仍有眾多的2.x版舊程式,所以本書將會同時兼顧,當有差異處時將會特別註明。以2.7、3.3、3.4版為主,這也是目前最新最普及的版本。
學習資訊科學相關知識時,免不了還是需要英文,因為許多第一手資料與文件,都只有英文,所以本書會放入英文詞彙,為了避免搞混,將會多次出現中英並呈,若原詞彙沒有適當且眾人公認的適當譯詞,或是直接使用原詞彙更顯得清楚明瞭時,將會直接使用原來的英文詞彙。
章節大綱:
第1章,介紹電腦的硬體與軟體,說明程式語言在其中扮演何種角色,簡述Python歷代版本的演進差異,然後下載並安裝Python實作,準備好開發環境,然後才能開始學習Python語言。
第2章,真正開始動手撰寫Python程式,從基本概念開始講起,介紹Python直譯器、何謂名稱與物件、指派的意義、各種運算式與述句、基本的資料型別、迴圈、函式、程式庫模組等。企圖以一章的篇幅介紹必備的基礎知識,有了這一章為底,接下來就可深入,繼續探究Python的各個面向。
第3章,介紹數值型別,包括整數、浮點數、複數、布林等等,以及可用的運算,介紹與數值相關的概念,譬如加總、平均、兩數的關係等等,數值是程式設計的基礎,說到底,電腦裡的所有資料終歸是一堆0與1、也就是數值罷了。之後會介紹具備特殊用處的十進位數和分數,以及整數的位元運算。
第4章,介紹Python的主力容器型別:序列,以及相關的迭代概念,這是一種一個接著一個、具備順序性的資料結構與操作方式,Python最重要的序列型別:序列,便是其中之一,許多議題與功能皆圍繞著串列打轉,譬如可迭代者與迭代器。除了串列外,還有元組與字串,並且介紹字串格式化。
第5章,介紹序列型別以外最重要的容器型別:字典,這是一種具備映射形式的的資料結構,每個元素都是所謂的鍵值配對,本章會介紹雜湊、集合等相關主題,最後簡介具有預設值和具有順序性的特殊字典。
第6章,函式是一門大學問,此章將從基礎逐步介紹函式的裡裡外外,包括如何定義、參數的傳遞、回傳值等基本知識,以及可被呼叫者和可視範圍等概念,並會以詳細的圖示解說何謂命名空間與環境,藉以了解遞迴、閉包、高階函式等進階主題,最後介紹直接由Python語法支援的產生器和延遲綁定的概念。
第7章,本章主題包括資料與編碼,重點放在檔案開啟與文字檔案,將會詳細解釋何謂文字編碼系統,期望能掃除此方面的疑惑,搞清楚底端的二進位資料只不過是一堆0與1(或說是一堆數字),須經過解釋後才具備意義;檔案是種抽象概念,不一定指硬碟裡的檔案,也可代表網路連線或其他資料讀寫來源。
第8章,認識的工具越多,便能根據狀況使用最適當的工具來解決問題,此章介紹串列和字典以外的其他容器型別,包括具名元組、雙向佇列、模組heapq、ChainMap、陣列等等。
第9章,函式實在太過重要,所以此章再談函式,再次深入探討,主題包括遞迴、尾呼叫、裝飾器、函數式程式設計、延遲執行等。
第10章,模組是管理大型軟體的重要利器,Python程式就是由模組所組成,本章介紹如何模組與套件的概念,如何建立模組,以及各種匯入模組並使用的語法,如何尋找、安裝、使用別人開發好的模組。
第11章,雖然至此章才介紹物件導向程式設計,但我們早已使用各種型別的物件撰寫程式;本章將介紹物件導向的主題,包括定義類別、封裝、繼承、重載、覆寫與多型,也會介紹多重繼承與後設類別。
第12章,現代程式語言碰見錯誤、無法執行、意外狀況時,都會提供一套異常處理機制來讓我們著手處理,本章介紹如何引發異常、該怎麼捕抓異常、如何自行定義異常類別。
第13章,學海無涯,此章將列出讀完本書後,接下來可進一步探索研究的主題。
附錄A,分類列出Python內建函式。
附錄B,概略列出Python 2.x與3.x版的差異。
附錄C,ASCII字元表,簡述ASCII和其在今時今日的用處,以及與其他文字編碼系統的關係。
附錄D,參考資料與學習資源,包括Python官方網站裡最常使用的頁面,學習Python的書籍著作與線上教材網站,程式設計的論壇、Q&A討論區、社群以及擷取最新資訊的新聞網站,並列出幾個不錯的練習題網站,藉以磨練寫程式與思考的能力。
原始碼:
書裡所有的原始程式碼檔案,都已上傳至
GitHub,可自由下載,直接點按網頁上的「Download ZIP」,便會將所有檔案打包成zip壓縮檔下載,或自行使用git指令下載;章節內文中都會註明相對應的檔名,此外,某些練習題需要的輔助檔案,也一併放在此處。
勘誤表:
若發現任何錯誤,還請留言告知,謝謝。嚴重程度分為三等:小、中、大。
在日期2016.03.15之前的錯誤,已在第5刷修正。
日期:2015.04.13
嚴重程度:中
位置:第27頁,第1行。
原文:因為Python有
可變物件(int、float、str)與
不可變物件(list)之分
修正:因為Python有
不可變物件(int、float、str)與
可變物件(list)之分
日期:2015.04.16
嚴重程度:中
位置:第26頁,下方程式碼區塊的第2行、第3行、第6行、最後一行。
原文:
>>> weight = 177 # 身高
修正:
>>> height = 177 # 身高
原文:
>>> height = 68 # 體重
修正:
>>> weight = 68 # 體重
原文:
>>> li4 = [name, weight, height, title, langs]
修正:
>>> li4 = [name, height, weight, title, langs]
原文:
['Frank', 185, 75, 'engineer', ['C', 'Python']]
修正:
['Frank', 177, 75, 'engineer', ['C', 'Python']]
日期:2015.04.16
位置:第71頁,2.7節中的第2小節標題。把全形冒號改成半形冒號。
嚴重程度:小
原文:忘記冒號「
:」
修正:忘記冒號「
:」
日期:2015.04.19
嚴重程度:小
位置:第54頁,小節「return述句」的第一段。
原文:但可回傳
tuple物件,所以可把許多物件放在tuple裡,
修正:但可回傳
容器物件,所以可把許多物件放在tuple
或list裡,
日期:2015.04.19
位置:第49頁,小節「break述句與continue述句」的第1行。
嚴重程度:小
原文:
使用迴圈述句(包括while與for)
時,有時處理到某輪
時,
修正:迴圈述句(包括while與for)
若處理到某輪
、
日期:2015.04.19
位置:第52頁,下方程式碼區塊的上面那一段。
嚴重程度:小
原文:函式定義完成後,
便可使用它,
修正:函式定義完成後,
原文:函式呼叫屬於運算式
修正:函式呼叫
在Python語法中屬於運算式
原文:在括號內傳入適當的參數
修正:在括號內傳入適當的參數
。
日期:2015.04.30
嚴重程度:中
位置:第57頁,第三個程式碼區塊的第5行,註解
原文:任何數的0次方都是
0,包括0
修正:任何數的0次方都是
1,包括0
日期:2015.04.30
位置:第59頁,最後一行。
嚴重程度:小
原文:呼叫
boo()可得知某物件代表的真假值。
修正:呼叫
bool()可得知某物件代表的真假值。
日期:2015.05.05
嚴重程度:小
位置:第46頁,倒數第三段、第一行。
原文:首輪的i是
0
修正:首輪的i是
1
日期:2015.05.05
嚴重程度:中
位置:第236頁,程式碼區塊的第5行
原文:return n * fact(
n)
修正:return n * fact(
n-1)
日期:2015.05.05
嚴重程度:中
位置:第263頁,第一個程式碼區塊最後一行的註解
原文:# 印出0、5、
15
修正:# 印出0、5、
10
日期:2015.05.05
嚴重程度:中
位置:第263頁,第二個程式碼區塊,第1行跟最後一行的註解
原文:x
+n
修正:x
*n
原文:# 印出0、5、
15
修正:# 印出0、5、
10
日期:2015.05.12
嚴重程度:中
位置:第36頁,第一個程式碼倒數第二行
原文:>>>
li0 or li2
修正:>>>
li1 or li2
日期:2015.06.05
位置:第22頁,倒數第二段的倒數第三行。
嚴重程度:小
原文:a最後會指向整數物件
修正:a最後會指向整數物件
7
日期:2015.06.05
位置:第29頁,第一段的第二行,末尾。
嚴重程度:小
原文:所以必須
如上述程式碼加個逗號
修正:所以必須加個逗號
日期:2015.06.06
嚴重程度:大
位置:第496頁,上面程式碼區塊
原文:
for i in range(num_agents):
t = Thread(target=sell_tickets, args=(i, num_tickets,
Lock()))
t.start()
修正:
lock = Lock()
for i in range(num_agents):
t = Thread(target=sell_tickets, args=(i, num_tickets,
lock))
t.start()
日期:2015.06.17
位置:第40頁,上面的程式碼區塊,倒數第三行。
嚴重程度:小
原文:
# 注意i先成為1,然後才指派x[i]
修正:
# 注意,i先被指派為1,然後x[i](x[1])才被指派為2
日期:2015.06.23
位置:第107頁,練習題3.3,第二行。
嚴重程度:小
原文:直到最後得到的和
是3
修正:直到最後得到的和
可被3整除
日期:2015.06.25
位置:第414頁,倒數第三行。
嚴重程度:小
原文:未免太多陽春
修正:未免太過陽春
日期:2015.06.25
位置:第7頁,第三段、倒數第二行。
嚴重程度:小
原文:PythonXY、Anaconda Python等
修正:Python(X,Y)、Continuum Analytics的Anaconda、Enthought Canopy等
日期:2015.06.26
嚴重程度:小
位置:第33頁,底下程式碼區塊,倒數第二行與第四行
原文:# a
等於b嗎?
修正:# a
不等於b嗎?
原文:# a
等於b嗎?2.x版才有「<>」
修正:# a
不等於b嗎?2.x版才有「<>」
日期:2015.06.29
嚴重程度:中
位置:第107頁,練習題3.7的圖3.1。
原文:
修正:
日期:2015.07.16
嚴重程度:小
位置:第126頁,上面的程式碼區塊,第12行的註解
原文:
刪除奇數位置的元素
修正:
刪除從索引值0開始、每隔2個位置的元素,直到最後
日期:2015.07.19
嚴重程度:小
位置:第360頁的程式碼區塊的註解
原文:# 0
非偶數
修正:# 0
不是奇數
原文:#
n是不是奇數,等同於n-1是不是偶數
修正:#
「n是不是奇數」等同於「n-1是不是偶數」
原文:#
n是不是偶數,等同於n-1是不是奇數
修正:#
「n是不是偶數」等同於「n-1是不是奇數」
日期:2015.07.21
嚴重程度:中
位置:第193頁,上面的程式碼區塊,倒數第七行
原文:
{3, 4, 5, 6}
修正:
{1, 3, 4, 5, 6}
日期:2015.07.26
嚴重程度:小
位置:第117頁,第一行。
原文:math、pi、circle
修正:math、pi、
c、circle
日期:2015.07.26
嚴重程度:小
位置:第133頁,上面程式碼區塊的第二行,應加上底下的註解:
修正:
# 注意li.copy(),3.x版的型別list才有方法copy
日期:2015.08.04
嚴重程度:小
位置:第284頁,上面程式碼區塊的第二行。
原文:f
w = open('testw.txt', 'w')
修正:f
out = open('testw.txt', 'w')
日期:2015.08.05
嚴重程度:小
位置:第43頁,下面程式碼區塊,倒數第五行。
原文:
... elif
修正:
>>> elif
日期:2015.08.12
嚴重程度:小
位置:第294頁,第一段第二行。
原文:
Uncode
修正:
Unicode
日期:2015.08.13
嚴重程度:小
位置:第407頁,第一行。
原文:form
sts
修正:form
ats
日期:2015.08.18
嚴重程度:小
位置:第459頁,上面程式碼區塊第五行,可去掉「as e」,不影響該處程式。
原文:except ValueError
as e:
修正:except ValueError:
日期:2015.08.18
嚴重程度:中
位置:第474頁,練習題12.1的程式碼區塊第三行。
原文:# raise
Except('hello')
修正:# raise
Exception('hello')
日期:2015.08.20
嚴重程度:小
位置:第464頁,程式碼12.2對應的檔名。
原文:(ch12_fact_exception
_2.py)
修正:(ch12_fact_exception.py)
日期:2015.09.27
嚴重程度:中
位置:第432頁,程式碼倒數第二行。
原文:c.bar
(c) # 呼叫
函式
修正:c.bar
() # 呼叫
方法
日期:2015.10.21
嚴重程度:中
位置:第376頁,程式區塊、下半段、第一行。
原文:
!even(n)
修正:
not even(n)
日期:2015.10.31
嚴重程度:大
位置:第459頁,上方程式區塊第六行。
原文:'
%s can not be less than 0'
修正:'
%s is not a number or is less than 0'
日期:2015.11.16
位置:第174頁,第二段、第三行。
嚴重程度:小
原文:從鍵映設到值
修正:從鍵映射到值
日期:2016.02.07
嚴重程度:小
位置:第115頁,第一段、最後一行。
原文:使用內建函式
instance
修正:使用內建函式
isinstance
日期:2016.02.09
位置:第375頁,倒數第二段、最後一行。
嚴重程度:小
原文:函式一般。
修正:函數。
日期:2016.02.12
嚴重程度:小
位置:第205頁,第二段、第二行。
原文:式
陣列(associative container)
修正:式
容器(associative container)
日期:2016.02.15
嚴重程度:大
位置:第250頁,上面的程式碼區塊
原文:for i in range(
k):
修正:for i in range(
len(items)):
位置:第250頁,第一段、第三行
原文:「for i in range(
k):」
修正:「for i in range(
len(items)):」
日期:2016.03.14
嚴重程度:小
位置:第v頁,目錄的1.2
說明:排版有誤,1.2 Python簡介的頁數「004」,應對齊最右邊
日期:2016.03.14
嚴重程度:小
位置:第xii頁,目錄的10.6
說明:排版有誤,目錄10.6的pip的頁數「418」,應對齊最右邊
在日期2016.03.15之前的錯誤,已在第5刷修正。
日期:2016.03.16
嚴重程度:小
位置:第40頁,第一段、第三行
原文:並無法修改指向的int物件
修正:並無法修改
所指向的int物件
日期:2016.03.16
嚴重程度:小
位置:第57頁,最下面的程式碼區塊,第一行的註解
說明:「#」應對齊其他行的註解
日期:2016.03.16
嚴重程度:小
位置:第284頁,上面程式碼區塊的底下那一段、第二行
原文:但這麼做會
一次載入檔案的全部內容
修正:但這麼做會
先載入檔案的全部內容
日期:2016.03.16
嚴重程度:小
位置:第316頁,倒數第三段、第一行
原文:否則甚少作低階的讀寫動作
修正:否則甚少
需要自己作低階的讀寫動作
日期:2016.03.16
嚴重程度:小
位置:第317頁,中間編輯器列表的第一行;刪除多餘的空格
原文:Visual Studio裡 的Binary Editor
修正:Visual Studio裡的Binary Editor
日期:2016.04.01
嚴重程度:小
位置:第306頁,倒數第二段、第一行
原文:
std.stderr
修正:
sys.stderr
日期:2016.04.21
嚴重程度:小
位置:第347頁,8.2節、第一段、第二行
原文:double-
dnded queue
修正:double-
ended queue
日期:2016.07.07
嚴重程度:小
位置:第ix頁,6.5節的第2小節
原文:函式回傳函式
修正:函式回傳函式與
nonlocal(3.x)
日期:2016.07.07
嚴重程度:小
位置:第35頁,上面程式區塊,第6行的註解
原文:# 注意
修正:# 注意
,不同運算式的結果指向同一物件
日期:2016.07.07
嚴重程度:小
位置:第40頁,第3行
原文:a、b與c並無法修改指向的int物件
修正:a、b與c並無法修改
所指向的int物件
日期:2016.07.07
嚴重程度:中
位置:第47頁,程式碼2.2的第5行
原文:while i <
5:
修正:while i <
n:
日期:2016.07.07
嚴重程度:小
位置:第98頁,上面程式區塊,第5行的註解
原文:取
的短名
修正:取
個短名
日期:2016.07.07
嚴重程度:小
位置:第115頁,第3行
原文:我們會稱呼某型別建立出來物件為「實體
修正:我們會稱呼某型別建立出來
的物件為「實體
日期:2016.07.07
嚴重程度:小
位置:第121頁,表4.3
說明:表格最後新增一列,內容為
操作動作:「sort(*, key=None, reverse=None)」
結果:「原地排序,3.x版才有」
日期:2016.07.07
嚴重程度:小
位置:第131頁,中間的程式區塊,第2行的註解
原文:# 找出
'a'的索引值
修正:# 找出
3的索引值
日期:2016.07.07
嚴重程度:中
位置:第132頁,第1行
原文:
2.x版才有sort,建議改用內建函式sorted
修正:
2.x版與3.x版都有sort,但參數稍有不同,與內建sorted同樣用法
日期:2016.07.07
嚴重程度:中
位置:第382頁,圖9.5
說明:圖9.5下面那一張圖不太正確,數字經過各個關卡後,可能會被過濾掉、可能會變化成其他數字(或別的物件),所以一開始若是「...3, 2, 1」,其他關卡不一定會看到。應把圖9.5換成底下這兩張圖。
首先是整批處理,range給出一整份資料,交給map。map處理完後,整批交給下個關卡。
若是延遲處理,range會陸續送出資料,經map處理後的資料已改變,如中間,但只處理部分。然後map把資料陸續送給filter,「5, 3, 2, 1, 1」過濾掉偶數後,filter送出的是「5, 3, 1, 1」。
日期:2016.07.07
嚴重程度:小
位置:第447頁,11.5之前的那一段,倒數第1行
原文:無法為
赴類別A、B建立一致的MRO
修正:無法為
父類別A、B建立
相容一致的MRO
日期:2016.07.12
嚴重程度:中
位置:第180頁,圖5.3
說明:應換成下圖。除了值,dict物件也要儲存鍵。注意,此僅為想像示意圖,非真實情況。
日期:2016.07.12
嚴重程度:中
位置:第181頁,圖5.4
說明:應換成下圖。set物件須儲存放進去的東西。注意,此僅為想像示意圖,非真實情況。
日期:2016.07.12
嚴重程度:小
位置:第272頁,小節「其他範圍」的倒數第二行
原文:產生器
生成式
修正:產生器
運算式
日期:2016.07.16
嚴重程度:小
位置:第255頁,圖6.22
說明:沒畫上垂直欄的攻擊黑線。請換成下圖:
日期:2016.07.19
嚴重程度:小
位置:第262頁,圖6.23,全域命名空間裡的名稱
原文:
makeMultipliers
修正:
make_multipliers
日期:2016.07.27
嚴重程度:小
位置:第231頁,程式碼區塊,第七行的註解
原文:# a、b、
c都是在區域(函式)範圍內第一次指派,
修正:# a、b、
d都是在區域(函式)範圍內第一次指派,
日期:2016.07.27
嚴重程度:小
位置:第231頁,程式碼區塊後第二行
原文:譬如li、a、b都屬於全域範圍內
修正:譬如
前三行的li、a、b都屬於全域範圍內
日期:2017.07.30
嚴重程度:小
位置:第76頁,第二個程式碼區塊,倒數第二行與倒數第四行
原文:
倒數第四行:>>>
x == y < z
倒數第二行:>>>
x == y and y < z
修正:
倒數第四行:>>>
x == y and y < z
倒數第二行:>>>
x == y < z
日期:2017.08.26
嚴重程度:小
位置:第265頁,最後一段的開頭
原文:
函式內只要使用了yield運算式,便成為產生器函式(generator function)、而非一般的函式,
修正:
def述句內若有yield運算式,便成為產生器函式(generator function)
的定義、而非一般的函式
定義,
日期:2017.09.09
嚴重程度:小
位置:第411頁,第9行
原文:那麼在 xyz 的 __init__.
init 裡
修正:那麼在 xyz 的 __init__.
py裡
日期:2017.09.09
嚴重程度:中
位置:第412頁,表10.1的「乙」
原文:乙 可 可
不可 可
修正:乙 可 可
可 不可
日期:2017.09.15
嚴重程度:小
位置:第466頁,最後一行
原文:但不會印出
foo。
修正:但不會印出
foo end。
日期:2019.0917
嚴重程度:中
位置:第28頁,倒數第四行
原文:t1與
t1指向同一個物件。
修正:t1與
t0指向同一個物件。