- 機(jī)器學(xué)習(xí)案例分析(基于Python語言)
- 王愷
- 9234字
- 2020-07-02 15:47:54
1.2 Python基礎(chǔ)
Python語言誕生于1990年,由荷蘭CWI(Centrum Wiskunde&Informatica,數(shù)學(xué)和計(jì)算機(jī)研究所)的Guido van Rossum設(shè)計(jì)并領(lǐng)導(dǎo)開發(fā)。Python語言具有簡單易學(xué)、免費(fèi)開源、跨平臺、高層語言、面向?qū)ο蟆⒇S富的庫、膠水語言等優(yōu)點(diǎn),已在系統(tǒng)編程、圖形界面開發(fā)、科學(xué)計(jì)算、文本處理、數(shù)據(jù)庫編程、網(wǎng)絡(luò)編程、Web開發(fā)、自動化運(yùn)維、金融分析、多媒體應(yīng)用、游戲開發(fā)、人工智能、網(wǎng)絡(luò)爬蟲等方面有著廣泛的應(yīng)用。
經(jīng)過20多年持續(xù)不斷的發(fā)展,Python語言經(jīng)歷了多個(gè)版本的更迭。目前使用的Python版本主要是Python2.x和Python3.x。但是Python3.x并不完全兼容Python2.x的語法,所以如果沒有特殊應(yīng)用需求,建議使用Python3.x版本。
1.2.1 Python編程環(huán)境
在Linux、Windows、MacOS等平臺上,都可以安裝Python語言環(huán)境以支持Python程序的運(yùn)行。但由于每個(gè)人使用Python的應(yīng)用場景不一樣,設(shè)置Python、安裝附加包,并沒有一個(gè)統(tǒng)一的解決方案,這里將給出Windows和MacOS系統(tǒng)中詳細(xì)的Python安裝說明。Linux系統(tǒng)的安裝細(xì)節(jié)取決于所用的Linux版本,這里不再詳細(xì)介紹。在正式介紹Python環(huán)境搭建之前,先給出Anaconda的簡單介紹。Anaconda是一個(gè)用于科學(xué)計(jì)算的Python/R發(fā)行版,支持Linux、Windows、MacOS系統(tǒng),提供了包管理與環(huán)境管理的功能,可以很方便地解決多版本Python并存、切換及各種第三方包安裝問題。使用Anaconda可以一次性地獲得300多種用于科學(xué)和工程計(jì)算相關(guān)任務(wù)的Python編程庫支持。
這里推薦使用免費(fèi)的Anaconda發(fā)布版搭建Python環(huán)境,這樣可以減少后續(xù)安裝Python各種包的麻煩,讀者可以從Anaconda官網(wǎng)的Download頁面(https://www.anaconda.com/distribution/)下載安裝包,如圖1-2所示。

圖1-2 Anaconda官網(wǎng)的Download頁面
單擊圖1-2下方的不同系統(tǒng)圖標(biāo),可以看到對應(yīng)系統(tǒng)下最新的安裝包,如圖1-3所示是Windows系統(tǒng)下的Anaconda安裝包。

圖1-3 Windows系統(tǒng)下的Anaconda安裝包
1.Windows
圖1-3列出了Windows系統(tǒng)中可下載文件列表,推薦下載Python3.7版本。讀者可以根據(jù)自己的操作系統(tǒng)版本選擇下載32位安裝包或64位安裝包。安裝包下載完成后,按照官網(wǎng)上的安裝說明進(jìn)行安裝即可。
安裝完成后需要確定所有設(shè)置是否正確。單擊“開始”菜單,運(yùn)行cmd命令,打開如圖1-4所示的操作系統(tǒng)的命令提示符界面。通過輸入Python命令可以啟動Python解釋器,此時(shí)進(jìn)入Python控制臺,并能看到所安裝的Python版本信息(圖1-4中顯示的Python版本是3.7.3)。

圖1-4 操作系統(tǒng)的命令提示符界面
提示圖1-4中出現(xiàn)警告信息是因?yàn)闆]有激活A(yù)naconda的虛擬環(huán)境。可以通過activate命令進(jìn)入Anaconda設(shè)定的虛擬環(huán)境。如果activate后面什么參數(shù)都不加,則會進(jìn)入Anaconda自帶的base環(huán)境。
安裝完成后會在“開始”菜單中多出以下幾個(gè)應(yīng)用。
Anaconda Navigator:用于管理工具包和環(huán)境的圖形用戶界面,后續(xù)涉及的眾多管理命令也可以在Navigator中手工實(shí)現(xiàn)。
Anaconda Prompt:使用命令行界面來管理環(huán)境和包。
Jupyter Notebook:基于Web的交互式計(jì)算環(huán)境,可以編輯易于人們閱讀的文檔,用于展示數(shù)據(jù)分析的過程。本書中的全部示例程序都基于Jupyter Notebook運(yùn)行,并展示運(yùn)行結(jié)果。
Spyder:一個(gè)使用Python語言的跨平臺的科學(xué)運(yùn)算集成開發(fā)環(huán)境。
使用Anaconda Navigator啟動應(yīng)用程序,然后使用Spyder和Jupyter Notebook即可開始Python編程之旅。Anaconda Navigator的界面如圖1-5所示。

圖1-5 Anaconda Navigator的界面
2.MacOS
下載OS X版的Anaconda安裝器,命名如Anaconda3-2019.03-MacOSX-x86_64.pkg。雙擊.pkg文件運(yùn)行安裝器。安裝器運(yùn)行時(shí),會自動將Anaconda執(zhí)行路徑添加到系統(tǒng)的.bash_profile文件中,該文件位于/User/$USER/.bash_profile。
可以通過在系統(tǒng)命令行運(yùn)行IPython來確認(rèn)安裝是否正常。
3.Linux
Linux下的安裝細(xì)節(jié)取決于所用的Linux版本,本書不再詳細(xì)介紹。
提示如果讀者想安裝Anaconda并不包含的額外的Python包,可以通過以下命令進(jìn)行安裝:
conda install package_name
如果上述命令不起作用,則可以使用pip包管理工具進(jìn)行安裝:
pip install package_name
還可以使用conda update命令來更新包:
conda update package_name
pip也支持通過-upgrade標(biāo)識進(jìn)行包的升級:
pip install-upgrade package_name
但是,當(dāng)能夠同時(shí)使用conda和pip進(jìn)行包安裝時(shí),請不要嘗試使用pip更新conda安裝的包,否則可能會導(dǎo)致環(huán)境問題。
◎ 操作練習(xí)1-1
請?jiān)谧约旱南到y(tǒng)中安裝Anaconda,并通過Anaconda Navigator打開Jupyter Notebook,新建Python 3代碼文件,并運(yùn)行:

【操作步驟】
單擊圖1-5中Jupyter圖標(biāo)下方的Launch即可啟動Jupyter Notebook,在瀏覽器出現(xiàn)的界面中選擇New→Python 3,即可新建Python 3代碼文件,如圖1-6所示。

圖1-6 新建Python 3代碼文件
運(yùn)行結(jié)果如圖1-7所示(輸入代碼后,單擊圖1-7中工具欄上的“運(yùn)行”即可)。

圖1-7 操作練習(xí)1-1運(yùn)行結(jié)果示例
提示在Jupyter Notebook中可以選擇File→Save as將當(dāng)前界面中輸入的代碼保存為.ipynb文件,該文件中不僅保存了代碼,而且保存了運(yùn)行結(jié)果。如果要恢復(fù)上次的運(yùn)行環(huán)境,直接打開對應(yīng)的.ipynb文件即可。也可以直接單擊左上角Jupyter旁邊的默認(rèn)文件名(圖1-7中所示為Untitled),直接將該文件重命名(推薦使用該方式)。
Jupyter Notebook默認(rèn)保存為.ipynb格式的文件,如果需要保存為.py格式的Python腳本文件,則可以選擇File→Download as→Python (.py)。
Jupyter Notebook的默認(rèn)工作路徑是當(dāng)前用戶的路徑,由于用戶路徑在系統(tǒng)盤中,因此會有一些操作權(quán)限限制。建議讀者在使用Jupyter Notebook前,重新設(shè)置工作路徑。
◎ 操作練習(xí)1-2
請將Jupyter Notebook的工作路徑設(shè)置為d:\jupyter-notebook。
【操作步驟】
(1)在“開始”菜單中運(yùn)行Anaconda Prompt,打開如圖1-8所示的Anaconda命令提示符界面,輸入命令:jupyter notebook-generate-config。運(yùn)行后,可看到生成的Jupyter Notebook配置文件路徑(圖1-8顯示的路徑是C:\Users\admin\.jupyter\jupyter_notebook_config.py)。

圖1-8 Anaconda命令提示符界面
(2)使用文本編輯器(如“記事本”等)編輯Jupyter Notebook配置文件,在文件中搜索c.NotebookApp.notebook_dir,在下面加一行,將Jupyter Notebook的工作路徑設(shè)置為d:\jupyter-notebook,如圖1-9所示。需要注意,工作路徑必須已存在,如果不存在,則無法正常啟動Jupyter Notebook。因此,請?jiān)谠O(shè)置工作路徑前在D盤創(chuàng)建jupyter-notebook文件夾。

圖1-9 修改Jupyter Notebook工作路徑
(3)重新啟動Jupyter Notebook,設(shè)置生效。重新完成操作練習(xí)1-1后,可以在d:\jupyter-notebook目錄下看到創(chuàng)建的.ipynb文件。
1.2.2 基本數(shù)據(jù)類型
一種編程語言所支持的數(shù)據(jù)類型決定了該編程語言所能保存的數(shù)據(jù)。Python語言常用的內(nèi)置數(shù)據(jù)類型包括Number(數(shù)字)、String(字符串)、List(列表)、Tuple(元組)、Set(集合)和Dictionary(字典)。
1.Number
Python中有3種不同的數(shù)字類型,分別是int(整數(shù)類型)、float(浮點(diǎn)類型)和complex(復(fù)數(shù)類型)。
整數(shù)類型與數(shù)學(xué)中的整數(shù)概念一致。整型數(shù)字包括正整數(shù)、0和負(fù)整數(shù),不帶小數(shù)點(diǎn),無大小限制。整數(shù)可以使用不同的進(jìn)制表示:不加任何前綴為十進(jìn)制整數(shù);加前綴0o為八進(jìn)制整數(shù);加前綴0x則為十六進(jìn)制整數(shù)。
浮點(diǎn)類型與數(shù)學(xué)中實(shí)數(shù)的概念一致,表示帶有小數(shù)的數(shù)值。Python語言要求所有浮點(diǎn)數(shù)必須帶有小數(shù)部分,小數(shù)部分可以是0,這種設(shè)計(jì)可以區(qū)分浮點(diǎn)數(shù)和整數(shù)。浮點(diǎn)數(shù)有兩種表示方法:十進(jìn)制表示和科學(xué)計(jì)數(shù)法表示。
復(fù)數(shù)類型表示數(shù)學(xué)中的復(fù)數(shù)。復(fù)數(shù)由實(shí)部和虛部組成,每一部分都是一個(gè)浮點(diǎn)數(shù),其書寫方法如下:
a+bj或a+bJ
其中,a和b是兩個(gè)數(shù)字,j或J是虛部的后綴,即a是實(shí)部,b是虛部。
Python中提供了9個(gè)基本的數(shù)值運(yùn)算操作符,如表1-1所示。
表1-1 9個(gè)基本的數(shù)值運(yùn)算操作符

◎ 操作練習(xí)1-3
請按圖1-10所示輸入代碼并運(yùn)行。

圖1-10 算術(shù)運(yùn)算示例
2.String
文本在程序中用字符串(String)類型來表示。Python語言中只有用于保存字符串的String類型,而沒有用于保存單個(gè)字符的數(shù)據(jù)類型。Python中的字符串可以寫在一對單引號中,也可以寫在一對雙引號或一對三引號(三個(gè)連續(xù)的單引號或三個(gè)連續(xù)的雙引號)中。其中,單引號和雙引號都可以表示單行字符串,兩者作用相同。使用單引號時(shí),雙引號可以作為字符串的一部分;使用雙引號時(shí),單引號可以作為字符串的一部分。三引號可以表示單行或者多行字符串。
不包含任何字符的字符串,如''(一對單引號)或""(一對雙引號),稱為空字符串(簡稱空串)。
在字符串中,可以使用轉(zhuǎn)義字符,常用的轉(zhuǎn)義字符如表1-2所示。
表1-2 常用的轉(zhuǎn)義字符

◎ 操作練習(xí)1-4
請按圖1-11所示輸入代碼并運(yùn)行。提示:在Jupyter Notebook的Python代碼編輯頁面中選擇View→Toggle Line Numbers即可進(jìn)行是否顯示行號的切換。

圖1-11 創(chuàng)建字符串示例
如果取消s2(第3行)和print(s2)(第8行)前的注釋符,程序會報(bào)SyntaxError錯(cuò)誤。
利用下標(biāo)“[]”可以從字符串中截取一個(gè)子串,其語法格式如下:
s[beg:end]
其中,s為原始字符串,beg是要截取子串在s中的起始下標(biāo),end是要截取子串在s中的結(jié)束下標(biāo)。省略beg,則表示從s的開始字符進(jìn)行子串截取,等價(jià)于s[0:end];省略end,則表示截取的子串包含從beg位置到最后一個(gè)字符之間的字符(包括最后一個(gè)字符);beg和end都省略,則表示子串中包含s中的所有字符。
注意 s[beg:end]截取子串中包含的字符是s中從beg至end-1(不包括end)位置上的字符。
Python中,對字符串中字符的下標(biāo)有兩種索引方式:從前向后索引和從后向前索引。如圖1-12所示,從前向后索引方式中第1個(gè)字符的下標(biāo)為0,其他字符的下標(biāo)是前一個(gè)字符的下標(biāo)加1;從后向前索引方式中,最后一個(gè)字符的下標(biāo)為-1,其他字符的下標(biāo)是后一個(gè)字符下標(biāo)減1。

圖1-12 字符串索引方式示例
◎ 操作練習(xí)1-5
請按圖1-13所示輸入代碼并運(yùn)行。

圖1-13 字符串操作示例
Python提供了5個(gè)基本的字符串操作符,如表1-3所示。
表1-3 5個(gè)基本的字符串操作符

3.List
List(列表)是Python中一種非常重要的數(shù)據(jù)類型。列表中可以包含多個(gè)元素,且元素類型可以不同。每一個(gè)元素可以是任一數(shù)據(jù)類型,包括數(shù)字、字符串、列表及后面要介紹的元組、集合、字典。所有元素都寫在一對方括號中,每兩個(gè)元素之間用逗號分隔。不包含任何元素的列表([])稱為空列表。
列表中元素的索引方式與字符串中元素的索引方式完全相同,也支持從前向后索引和從后向前索引兩種方式。
◎ 操作練習(xí)1-6
請按圖1-14所示輸入代碼并運(yùn)行。

圖1-14 列表操作示例
4.Tuple
Tuple(元組)與列表類似,可以包含多個(gè)元素,且元素類型可以不相同,書寫時(shí)每兩個(gè)元素之間用逗號分隔。與列表不同之處在于:元組的所有元素都寫在一對小括號中,且元組中的元素不能修改。不包含任何元素的元組(())稱為空元組。
元組中元素的索引方式與列表和字符串中元素的索引方式完全相同。
◎ 操作練習(xí)1-7
請按圖1-15所示輸入代碼并運(yùn)行。

圖1-15 元組操作示例
5.Set
與元組和列表類似,Set(集合)中同樣可以包含多個(gè)不同類型的元素,但集合中的各元素?zé)o序,不允許有相同值的元素,并且元素必須是可哈希(Hashable)對象。集合的主要作用是進(jìn)行元素的快速檢索,以及進(jìn)行交集、并集等集合運(yùn)算。
集合中所有元素都寫在一對大括號中,各元素之間用逗號分隔。不包含任何元素的集合稱為空集合。需要注意,創(chuàng)建空集合需要使用set函數(shù),直接寫{}表示創(chuàng)建一個(gè)空字典。
◎ 操作練習(xí)1-8
請按圖1-16所示輸入代碼并運(yùn)行。

圖1-16 創(chuàng)建集合示例
6.Dictionary
Dictionary(字典)是另一種無序的對象集合。但與集合不同,字典是一種映射類型,每一個(gè)元素是一個(gè)鍵(key):值(value)對。在一個(gè)字典對象中,鍵必須是唯一的,即不同元素的鍵不能相同;鍵必須是可哈希數(shù)據(jù),即鍵不能是列表、元組、集合、字典等類型;值可以是任意類型。字典中的所有元素(鍵:值對)都寫在一對大括號中,各元素之間用逗號分隔。不包含任何元素的字典({})稱為空字典。
創(chuàng)建字典時(shí),既可以使用大括號,也可以使用dict函數(shù)。如果要?jiǎng)?chuàng)建一個(gè)空字典,可以使用{}或dict(),如圖1-17所示。

圖1-17 創(chuàng)建空字典
◎ 操作練習(xí)1-9
請按圖1-18所示輸入代碼并運(yùn)行。

圖1-18 創(chuàng)建字典示例
提示zip函數(shù)的參數(shù)是多個(gè)可迭代的對象(列表等),其功能是將不同對象中對應(yīng)的元素分別打包成元組,然后返回由這些元組組成的列表。在Python3.x中為了減少內(nèi)存,zip函數(shù)返回的是一個(gè)對象,可以通過list函數(shù)轉(zhuǎn)換成列表,如通過list(zip(['one','two','three'],[1,2,3]))可得到列表[('one',1),('two',2),('three',3)]。
1.2.3 分支語句和循環(huán)語句
程序由3種基本結(jié)構(gòu)組成:順序結(jié)構(gòu)、分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。這些基本結(jié)構(gòu)都有一個(gè)入口和一個(gè)出口。
● 順序結(jié)構(gòu)是程序按照線性順序依次執(zhí)行的一種運(yùn)行方式。
● 分支結(jié)構(gòu)是程序根據(jù)條件判斷結(jié)果而選擇不同向前執(zhí)行路徑的一種運(yùn)行方式,根據(jù)分支路徑上的完備性,分支結(jié)構(gòu)包括單分支結(jié)構(gòu)、二分支結(jié)構(gòu)和多分支結(jié)構(gòu)。
● 循環(huán)結(jié)構(gòu)是程序根據(jù)條件判斷結(jié)果向后反復(fù)執(zhí)行的一種運(yùn)行方式,根據(jù)循環(huán)體觸發(fā)條件不同,循環(huán)結(jié)構(gòu)包括條件循環(huán)結(jié)構(gòu)和遍歷循環(huán)結(jié)構(gòu)。
1.分支語句
分支語句是控制程序運(yùn)行的一類重要語句,它的作用是根據(jù)判斷條件選擇程序執(zhí)行路徑,使用方式如下:

其中,if、elif、else都是保留字,else后面不設(shè)置條件,表示不滿足if和elif語句的其他情況。最簡單的條件語句只有if,elif和else都是可選項(xiàng),根據(jù)需要決定是否使用。
◎ 操作練習(xí)1-10
請按圖1-19所示輸入代碼并運(yùn)行。

圖1-19 if、elif和else語句使用示例
其中,第2行if語句包含第一個(gè)條件表達(dá)式,當(dāng)表達(dá)式返回True時(shí),執(zhí)行第3條語句,如果返回False,則執(zhí)行第4行的elif語句,判斷下一個(gè)條件。同理,如果條件成立,則繼續(xù)執(zhí)行第5行語句,否則執(zhí)行第6行語句。如果所有if、elif條件都不滿足,則執(zhí)行第10條else語句,該語句表示用戶輸入的成績在大于90且小于或等于100的范圍內(nèi)。
2.循環(huán)語句
循環(huán)語句是控制程序運(yùn)行的一類重要語句,與分支語句控制程序執(zhí)行類似,它的作用是根據(jù)判斷條件確定一段程序是否再次執(zhí)行一次或者多次。
循環(huán)結(jié)構(gòu)流程圖如圖1-20所示。其中,語句序列1和語句序列3分別是循環(huán)語句前和循環(huán)語句后所執(zhí)行的操作。循環(huán)條件判斷和語句序列2構(gòu)成了循環(huán)語句:只要滿足循環(huán)條件,就會執(zhí)行循環(huán)語句2;執(zhí)行循環(huán)語句2后,會再次判斷是否滿足循環(huán)條件。

圖1-20 循環(huán)結(jié)構(gòu)流程圖
這里介紹Python中兩種循環(huán)語句的使用方法:for循環(huán)和while循環(huán)。
1)for循環(huán)
Python語言中的for循環(huán)用于遍歷可迭代對象中的每一個(gè)元素,并根據(jù)當(dāng)前訪問的元素做數(shù)據(jù)處理,其語法格式如下:

變量依次取可迭代對象中每一個(gè)元素的值,在語句序列中可以根據(jù)當(dāng)前變量保存的元素值進(jìn)行相應(yīng)的數(shù)據(jù)處理。
◎ 操作練習(xí)1-11 使用for循環(huán)遍歷列表
按圖1-21所示輸入代碼并運(yùn)行。

圖1-21 for循環(huán)使用示例
2)while循環(huán)
Python中while循環(huán)的語法格式如下:

當(dāng)循環(huán)條件返回True時(shí),執(zhí)行語句序列;執(zhí)行語句序列后,再判斷循環(huán)條件是否成立。
◎ 操作練習(xí)1-12 使用while循環(huán)求n!
按圖1-22所示輸入代碼并運(yùn)行。

圖1-22 while循環(huán)使用示例
運(yùn)行程序后,如果輸入5,則輸出120;如果輸入7,則輸出5040。
1.2.4 函數(shù)
函數(shù)可以理解為對一組表達(dá)特定功能表達(dá)式的封裝,它與數(shù)學(xué)函數(shù)類似,能夠接收變量并輸出結(jié)果。在Python中,函數(shù)是實(shí)現(xiàn)模塊化的工具。
1.函數(shù)的定義與調(diào)用
Python語言中使用函數(shù)分為兩個(gè)步驟:定義函數(shù)和調(diào)用函數(shù)。
Python語言中定義函數(shù)需要使用def關(guān)鍵字,下面通過一個(gè)簡單的例子直觀地了解定義和調(diào)用函數(shù)的過程。
◎ 操作練習(xí)1-13 函數(shù)定義和調(diào)用示例
按圖1-23所示輸入代碼并運(yùn)行。

圖1-23 函數(shù)定義和調(diào)用示例
2.參數(shù)列表和返回值
通過函數(shù)的參數(shù)列表,可以為函數(shù)傳入待處理的數(shù)據(jù),從而使一個(gè)函數(shù)更加通用。
1)形參
形參的全稱是形式參數(shù),即定義函數(shù)時(shí)函數(shù)名后面的一對小括號中給出的參數(shù)列表。形參只能在函數(shù)中使用,其作用是接收函數(shù)調(diào)用時(shí)傳入的參數(shù)值,并在函數(shù)中參與運(yùn)算。
2)實(shí)參
實(shí)參的全稱是實(shí)際參數(shù),即調(diào)用函數(shù)時(shí)函數(shù)名后面一對小括號中給出的參數(shù)列表。當(dāng)調(diào)用函數(shù)時(shí),會將實(shí)參的值傳遞給對應(yīng)的形參,函數(shù)中再利用形參進(jìn)行運(yùn)算,得到結(jié)果。
3)默認(rèn)參數(shù)
函數(shù)的默認(rèn)參數(shù)就是缺省參數(shù),即當(dāng)調(diào)用函數(shù)時(shí),如果沒有為某些形參傳遞對應(yīng)的實(shí)參,則這些形參會自動使用默認(rèn)參數(shù)值。
4)關(guān)鍵字參數(shù)
在調(diào)用函數(shù)時(shí),除了前面那種通過位置來體現(xiàn)實(shí)參和形參的對應(yīng)關(guān)系的方法(位置參數(shù)),還有一種使用關(guān)鍵字參數(shù)的方法,其形式為“形參=實(shí)參”。
在使用關(guān)鍵字參數(shù)調(diào)用函數(shù)時(shí),實(shí)參的傳遞順序可以與形參列表中形參的順序不一致。這樣,當(dāng)一個(gè)函數(shù)的很多參數(shù)都有默認(rèn)值,而只想對其中一小部分帶默認(rèn)值的參數(shù)傳遞實(shí)參時(shí),就可以直接通過關(guān)鍵字參數(shù)的方式來進(jìn)行實(shí)參傳遞,而不必考慮這些帶默認(rèn)值的參數(shù)在形參列表中的實(shí)際位置。
5)不定長參數(shù)
不定長參數(shù),即在調(diào)用函數(shù)時(shí)可以接收任意數(shù)量的實(shí)參,這些實(shí)參在傳遞給函數(shù)時(shí)會被封裝成元組(位置參數(shù))或字典(關(guān)鍵字參數(shù))形式。一般情況下,不定長參數(shù)放在形參表的最后,前面?zhèn)魅氲膶?shí)參與普通形參一一對應(yīng),而后面剩余的實(shí)參會在被封裝成元組或字典后傳給不定長參數(shù)。
6)拆分參數(shù)列表
如果一個(gè)函數(shù)所需要的參數(shù)已經(jīng)存儲在列表、元組或字典中,就可以直接從列表、元組或字典中拆分出函數(shù)所需要的參數(shù),其中列表、元組拆分出來的結(jié)果作為位置參數(shù),而字典拆分出來的結(jié)果作為關(guān)鍵字參數(shù)。
7)返回值
通過返回值,可以將函數(shù)的計(jì)算結(jié)果返回到函數(shù)調(diào)用的位置,從而可以利用函數(shù)調(diào)用返回的結(jié)果再去進(jìn)行其他運(yùn)算。前面的很多例子中都利用了print函數(shù)將計(jì)算結(jié)果輸出在屏幕上,但無法再獲取這些顯示在屏幕上的結(jié)果以參與其他運(yùn)算。如果希望一個(gè)函數(shù)的運(yùn)算結(jié)果返回到調(diào)用函數(shù)的位置,從而可以繼續(xù)用該結(jié)果參與其他運(yùn)算,那么應(yīng)使用return語句。
8)lambda函數(shù)
lambda函數(shù)也稱匿名函數(shù),是一種不使用def定義函數(shù)的形式,其作用是能快速定義一個(gè)簡短的函數(shù)。lambda函數(shù)的函數(shù)體只是一個(gè)表達(dá)式,所以lambda函數(shù)通常只能實(shí)現(xiàn)比較簡單的功能。其語法格式為
lambda [參數(shù)1[,參數(shù)2,…,參數(shù)n]]:表達(dá)式
冒號后面的表達(dá)式的計(jì)算結(jié)果即該lambda函數(shù)的返回值。
◎ 操作練習(xí)1-14 形參、實(shí)參和返回值示例
按圖1-24所示輸入代碼并運(yùn)行。

圖1-24 形參、實(shí)參和返回值示例
◎ 操作練習(xí)1-15 默認(rèn)參數(shù)、關(guān)鍵字參數(shù)、不定長參數(shù)示例
按圖1-25所示輸入代碼并運(yùn)行。

圖1-25 默認(rèn)參數(shù)、關(guān)鍵字參數(shù)、不定長參數(shù)示例
◎ 操作練習(xí)1-16 拆分參數(shù)列表示例
按圖1-26所示輸入代碼并運(yùn)行。

圖1-26 拆分參數(shù)列表示例
◎ 操作練習(xí)1-17lambda函數(shù)示例
按圖1-27所示輸入代碼并運(yùn)行。

圖1-27 lambda函數(shù)示例
1.2.5 類和對象
類與對象是面向?qū)ο蟪绦蛟O(shè)計(jì)的兩個(gè)重要概念。類和對象的關(guān)系即數(shù)據(jù)類型與變量之間的關(guān)系,使用一個(gè)類可以創(chuàng)建多個(gè)對象,而每個(gè)對象只能是某一個(gè)類的對象。類規(guī)定了可以用于存儲什么數(shù)據(jù),而對象用于實(shí)際存儲數(shù)據(jù)。
1.類的基本概念
一個(gè)類中可以包含屬性和方法。屬性對應(yīng)一個(gè)類可以保存哪些數(shù)據(jù),而方法對應(yīng)一個(gè)類可以支持哪些操作。對象是類的實(shí)例。
提示類中的屬性對應(yīng)前面所學(xué)習(xí)的變量,而類中的方法對應(yīng)前面所學(xué)習(xí)的函數(shù)。通過類,可以把數(shù)據(jù)和操作封裝在一起,從而使得程序結(jié)構(gòu)更加清晰,這也就是所謂的類的封裝性。
1)創(chuàng)建類
使用class語句來創(chuàng)建一個(gè)新類,class之后為類的名稱,并以冒號結(jié)尾。其形式如下:

class_suite由類成員、方法和數(shù)據(jù)屬性組成。
定義了一個(gè)類后,就可以創(chuàng)建該類的實(shí)例對象,其語法格式如下:
類名(參數(shù)表)
◎ 操作練習(xí)1-18 創(chuàng)建一個(gè)空類
按圖1-28所示輸入代碼并運(yùn)行。

圖1-28 創(chuàng)建一個(gè)空類
從輸出結(jié)果可以看到,em是Employee類的對象,其地址為0x0000000005D26588。注意,因?yàn)槊看芜\(yùn)行時(shí)給對象分配的內(nèi)存空間可能不同,所以輸出的對象地址也會有所不同。
2)類屬性及其訪問
一個(gè)類中可以包含屬性和方法,屬性對應(yīng)一個(gè)類對象可以保存的數(shù)據(jù)。可以在定義類時(shí)指定該類的屬性。
對類屬性的訪問,既可以通過類名進(jìn)行,也可以通過該類的對象進(jìn)行,訪問形式如下:
類名或?qū)ο竺?屬性名
◎ 操作練習(xí)1-19 類屬性訪問示例
按圖1-29所示輸入代碼并運(yùn)行。

圖1-29 類屬性訪問示例
提示從圖1-29可以看出,既可以獲取類屬性的值,也可以對類屬性賦值。
當(dāng)創(chuàng)建新對象時(shí),該對象中的類屬性的值即定義類時(shí)給類屬性賦的值。
當(dāng)使用類名對類屬性值做修改后,如果對象的該屬性沒有被重新賦值,則對象的屬性值也會隨之修改;如果對象的該屬性已被重新賦值,則對象的屬性值不會隨之修改。
當(dāng)使用對象名對屬性值做修改后,只會改變該對象的屬性值,類和其他對象的該屬性值不會隨之修改。
3)類中的方法
類中的方法分為兩類:普通方法和內(nèi)置方法。普通方法需要通過類的實(shí)例對象根據(jù)方法名調(diào)用,內(nèi)置方法是指在特定情況下由系統(tǒng)自動執(zhí)行。
普通方法要求第一個(gè)參數(shù)必須對應(yīng)調(diào)用方法時(shí)所使用的實(shí)例對象(一般命名為self,也可以改為其他名字)。當(dāng)使用一個(gè)實(shí)例對象調(diào)用類的普通方法時(shí),其語法格式如下:
實(shí)例對象名.方法名(實(shí)參列表)
常用的內(nèi)置方法包括構(gòu)造方法、析構(gòu)方法、__str__方法等。
● 構(gòu)造方法:其方法名為__init__,在創(chuàng)建一個(gè)類對象時(shí)會自動執(zhí)行,負(fù)責(zé)完成新創(chuàng)建對象的初始化工作。
● 析構(gòu)方法:其方法名為__del__,在銷毀一個(gè)類對象時(shí)會自動執(zhí)行,負(fù)責(zé)完成待銷毀對象的資源清理工作。
●__str__方法:在調(diào)用str函數(shù)對類對象進(jìn)行處理時(shí)或者調(diào)用Python內(nèi)置的format和print函數(shù)時(shí)自動執(zhí)行,__str__方法的返回值必須是字符串。
◎ 操作練習(xí)1-20 類的構(gòu)造方法示例
按圖1-30所示輸入代碼并運(yùn)行。

圖1-30 類的構(gòu)造方法示例
2.繼承與多態(tài)
除前面介紹的封裝性以外,繼承與多態(tài)是面向?qū)ο蟪绦蛟O(shè)計(jì)的另外兩個(gè)重要特性。通過繼承,可以基于已有類創(chuàng)建新的類,新類除了繼承已有類的所有屬性和方法,還可以根據(jù)需要增加新的屬性和方法。通過多態(tài),可以實(shí)現(xiàn)在執(zhí)行同一條語句時(shí),能根據(jù)實(shí)際使用的對象類型決定調(diào)用哪個(gè)方法。
1.2.6 打開、關(guān)閉、讀/寫文件
I/O編程可以將內(nèi)存中的數(shù)據(jù)以文件的形式保存到外存中,從而實(shí)現(xiàn)數(shù)據(jù)的長期保存及重復(fù)利用。同時(shí),也可以利用os模塊方便地使用與操作系統(tǒng)相關(guān)的功能,如生成文件路徑、創(chuàng)建不存在的目錄,為文件讀/寫操作提供輔助支持。
1.打開和關(guān)閉文件
使用open函數(shù)可以打開一個(gè)要做讀/寫操作的文件,其常用形式如下:

其中,filename是要打開文件的路徑;mode是打開文件的方式(表1-4),不同文件打開方式可以組合使用。使用open函數(shù)打開文件后會返回一個(gè)文件對象,利用該文件對象可完成文件中數(shù)據(jù)的讀/寫操作。
表1-4 文件打開方式

使用open函數(shù)打開文件并完成讀/寫操作后,必須使用文件對象的close方法將文件關(guān)閉。
使用with語句可以讓系統(tǒng)在文件操作完畢后自動關(guān)閉文件,從而避免忘記調(diào)用close方法而不能及時(shí)釋放文件資源的問題。
◎ 操作練習(xí)1-21 with語句使用示例
按圖1-31所示輸入代碼并運(yùn)行。

圖1-31 with語句使用示例
2.文件讀/寫
使用open函數(shù)打開文件后,即可使用返回的文件對象進(jìn)行文件讀/寫操作。下面介紹文件對象中讀/寫數(shù)據(jù)的幾種方法。
1)write方法
使用文件對象的write方法可以將字符串寫入文件中,其語法格式如下:

其中,f是open函數(shù)返回的文件對象,str是要寫入文件中的字符串。write方法執(zhí)行完畢后將返回寫入文件中的字符個(gè)數(shù)。
2)read方法
使用文件對象的read方法可以從文件中讀取數(shù)據(jù),其語法格式如下:

其中,f是open函數(shù)返回的文件對象;n指定了要讀取的字節(jié)數(shù),默認(rèn)值為-1,表示讀取文件中的所有數(shù)據(jù)。read方法將從文件中讀取的數(shù)據(jù)返回。
3)readline方法
使用文件對象的readline方法可以從文件中每次讀取一行數(shù)據(jù),其語法格式如下:

其中,f是open函數(shù)返回的文件對象。readline方法將從文件中讀取的一行數(shù)據(jù)返回。
4)readlines方法
使用文件對象的readlines方法可以從文件中按行讀取所有數(shù)據(jù),其語法格式如下:

其中,f是open函數(shù)返回的文件對象。readlines方法將從文件中按行讀取的所有數(shù)據(jù)以列表形式返回。
◎ 操作練習(xí)1-22 寫文件示例
按圖1-32所示輸入代碼并運(yùn)行。

圖1-32 寫文件示例
打開文件D:\python\test.txt,可以看到如下文件內(nèi)容:

即通過write方法向文件中寫入了兩行字符串。
◎ 操作練習(xí)1-23 讀文件示例
按圖1-33所示輸入代碼并運(yùn)行。

圖1-33 讀文件示例
1.2.7 異常處理
異常是指因程序運(yùn)行時(shí)發(fā)生錯(cuò)誤而產(chǎn)生的信號。如果程序中沒有對異常進(jìn)行處理,則程序會拋出該異常,并停止運(yùn)行。為了保證程序的穩(wěn)定性和容錯(cuò)性,需要在程序中捕獲可能的異常,并對其進(jìn)行處理,使得程序不會因異常而意外停止。
Python通過try、except等保留字提供異常處理功能,其語法格式如下:

try的工作原理是,當(dāng)開始一個(gè)try語句后,Python就在當(dāng)前程序的上下文中做標(biāo)記,這樣當(dāng)異常出現(xiàn)時(shí)就可以回到這里,try子句先執(zhí)行,接下來會發(fā)生什么依賴于執(zhí)行時(shí)是否出現(xiàn)異常。
● 如果try子句執(zhí)行時(shí)發(fā)生異常,Python就會執(zhí)行第一個(gè)匹配該異常的except子句。異常處理完畢,控制流就完成整個(gè)try語句的執(zhí)行,繼續(xù)執(zhí)行try語句后面的代碼(除非在處理異常時(shí)又引發(fā)新的異常)。
● 如果try子句執(zhí)行時(shí)發(fā)生異常,卻沒有匹配的except子句,異常將被傳遞到上層的try語句,或者到程序的最上層(這樣將結(jié)束程序,并打印默認(rèn)的出錯(cuò)信息)。
● 如果try子句執(zhí)行時(shí)沒有發(fā)生異常,Python將執(zhí)行else子句(如果有else的話);否則,else子句不會被執(zhí)行。
● finally是try except語句的一個(gè)可選項(xiàng)。無論try子句執(zhí)行時(shí)是否發(fā)生異常,finally子句都會被執(zhí)行。
除系統(tǒng)提供的異常類型以外,還可以自定義異常。自定義異常是指除了系統(tǒng)提供的異常類型,還可以根據(jù)需要定義新的異常。自定義異常,實(shí)際上就是以BaseException類作為父類創(chuàng)建一個(gè)子類。
◎ 操作練習(xí)1-24 異常處理示例
按圖1-34所示輸入代碼并運(yùn)行。

圖1-34 異常處理示例
- Clojure Data Analysis Cookbook
- 基于LPC3250的嵌入式Linux系統(tǒng)開發(fā)
- 自主研拋機(jī)器人技術(shù)
- Hands-On Linux for Architects
- 大型數(shù)據(jù)庫管理系統(tǒng)技術(shù)、應(yīng)用與實(shí)例分析:SQL Server 2005
- 工業(yè)控制系統(tǒng)測試與評價(jià)技術(shù)
- Linux內(nèi)核精析
- MongoDB 4 Quick Start Guide
- Visual Basic項(xiàng)目開發(fā)案例精粹
- Deep Learning Essentials
- 菜鳥起飛五筆打字高手
- 特征工程入門與實(shí)踐
- ASP.NET學(xué)習(xí)手冊
- Microsoft 365 Mobility and Security:Exam Guide MS-101
- 暗戰(zhàn)強(qiáng)人:黑客攻防入門全程圖解