python 快速教程(二)_第1頁(yè)
python 快速教程(二)_第2頁(yè)
python 快速教程(二)_第3頁(yè)
python 快速教程(二)_第4頁(yè)
python 快速教程(二)_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Python進(jìn)階01 詞典 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!通過我們的基礎(chǔ)教程,我們已經(jīng)對(duì)Python建立了基本概念,也對(duì)對(duì)象和類有一個(gè)相對(duì)明確的認(rèn)識(shí)。我們的進(jìn)階教程就是對(duì)基礎(chǔ)教程的進(jìn)一步拓展,進(jìn)一步了解Python的細(xì)節(jié)。希望在進(jìn)階教程之后,你可以對(duì)Python的基本語(yǔ)法有一個(gè)相對(duì)全面的認(rèn)識(shí)。之前我們說了,表是Python里的一個(gè)類。一個(gè)特定的表,比如說nl = 1,3,8,就是這個(gè)類的一個(gè)對(duì)象。我們可以調(diào)用這個(gè)對(duì)象的一些方法,比如 nl.append(15)?,F(xiàn)在,我們要介紹一個(gè)新的類,就是詞典 (dicti

2、onary)。與表相類似,詞典也可以儲(chǔ)存多個(gè)元素。這種可以用來儲(chǔ)存多個(gè)元素的對(duì)象統(tǒng)稱為容器(container)。1. 基本概念常見的創(chuàng)建詞典的方法:dic = tom:11, sam:57,lily:100print type(dic)詞典和表類似的地方,是包含有多個(gè)元素,每個(gè)元素以逗號(hào)分隔。但詞典的元素包含有兩部分,鍵和值,常見的是以字符串來表示鍵,也可以使用數(shù)字或者真值來表示鍵(不可變的對(duì)象可以作為鍵)。值可以是任意對(duì)象。鍵和值兩者一一對(duì)應(yīng)。(實(shí)際上,表的元素也可以是任意對(duì)象)比如上面的例子中,tom對(duì)應(yīng)11,sam對(duì)應(yīng)57,lily對(duì)應(yīng)100與表不同的是,詞典的元素沒有順序。你不能通過

3、下標(biāo)引用元素。詞典是通過鍵來引用。print dictomdictom = 30print dic可以構(gòu)建一個(gè)新的空的詞典:dic = print dic在詞典中增添一個(gè)新元素的方法:diclilei = 99print dic(引用一個(gè)新的鍵,賦予對(duì)應(yīng)的值)2. 對(duì)dictionary的元素進(jìn)行循環(huán)調(diào)用:dic = lilei: 90, lily: 100, sam: 57, tom: 90for key in dic: print dickey可以看到,在循環(huán)中,dict的一個(gè)鍵會(huì)提取出來賦予給key變量。通過print的結(jié)果,我們可以再次確認(rèn),dic中的元素是沒有順序的。3. 詞典的其它

4、常用方法print dic.keys() # 返回dic所有的鍵print dic.values() # 返回dic所有的值print dic.items() # 返回dic所有的元素(鍵值對(duì))dic.clear() # 清空dic,dict變?yōu)榱硗庥幸粋€(gè)很常用的用法:del dictom # 刪除 dic 的tom元素del是Python中保留的關(guān)鍵字,用于刪除對(duì)象。與表類似,你可以用len()查詢?cè)~典中的元素總數(shù)。print(len(dic)總結(jié):詞典的每個(gè)元素是鍵值對(duì)。元素沒有順序。dic = tom:11, sam:57,lily:100dictom = 99for key in di

5、c: .del, len()Python進(jìn)階02 文本文件的輸入輸出 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!Python具有基本的文本文件讀寫功能。Python的標(biāo)準(zhǔn)庫(kù)提供有更豐富的讀寫功能。文本文件的讀寫主要通過open()所構(gòu)建的文件對(duì)象來實(shí)現(xiàn)。1. 打開文件,創(chuàng)建文件對(duì)象。f = open(文件名,模式)最常用的模式有:r # 只讀“w” # 寫入2. 文件對(duì)象的方法:讀取方法:content = f.read(N) # 讀取N bytes的數(shù)據(jù)content = f.readline() # 讀取一行conte

6、nt = f.readlines() # 讀取所有行,儲(chǔ)存在表中,每個(gè)元素是一行。寫入方法:f.write(I like apple) # 將I like apple寫入文件關(guān)閉文件:f.close()3. 循環(huán)讀入文件:(該方法已經(jīng)從Python 3中刪除,請(qǐng)盡量避免使用)for line in file(文件名): print line利用file()函數(shù),我們創(chuàng)建了一個(gè)循環(huán)對(duì)象。在循環(huán)中,文件的每一行依次被讀取,賦予給line變量??偨Y(jié):f = open(name, r)line = f.readline()f.write(abc)f.close()Python進(jìn)階03 模塊 作者:Va

7、mei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!我們之前看到了函數(shù)和對(duì)象。從本質(zhì)上來說,它們都是為了更好的組織已經(jīng)有的程序,以方便重復(fù)利用。模塊(module)也是為了同樣的目的。在Python中,一個(gè).py文件就構(gòu)成一個(gè)模塊。通過模塊,你可以調(diào)用其它文件中的程序。1. 引入(import)和使用模塊我們先寫一個(gè)first.py文件,內(nèi)容如下:def laugh(): print HaHaHaHa再寫一個(gè)second.pyimport firstfor i in range(10): first.laugh()在second.py中,我們

8、并沒有定義laugh函數(shù),但通過從first中引入(import),我們就可以直接使用first.py中的laugh函數(shù)了。從上面可以看到,引入模塊后,我們可以通過 模塊.對(duì)象 的方式來調(diào)用所想要使用的對(duì)象。上面例子中,first為引入的模塊,laugh()是我們所引入的對(duì)象。此外,還有其它的引入方式, import a as b, from a import *, 都是處于方便書寫的原因,本質(zhì)上沒有差別。2. 搜索路徑Python會(huì)在以下路徑中搜索它想要尋找的模塊:1. 程序所在的文件夾2. 標(biāo)準(zhǔn)庫(kù)的安裝路徑3. 操作系統(tǒng)環(huán)境變量PYTHONPATH所包含的路徑如果你有自定義的模塊,或者下載

9、的模塊,可以根據(jù)情況放在相應(yīng)的路徑,以便python可以找到。3. 模塊包可以將功能相似的模塊放在同一個(gè)文件夾(比如說dir)中,通過import dir.module的方式引入。注意,該文件夾中必須包含一個(gè)_init_.py的文件,以便提醒python知道該文件夾為一個(gè)模塊包。_init_.py可以是一個(gè)空文件。總結(jié)import modulemodule.object_init_.pyPython進(jìn)階04 函數(shù)的參數(shù)對(duì)應(yīng) 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!我們已經(jīng)接觸過函數(shù)(function)的參數(shù)(argume

10、nts)傳遞, 當(dāng)時(shí)我們提到,參數(shù)是根據(jù)位置對(duì)應(yīng)傳遞的。這一次,我們準(zhǔn)備接觸更多的參數(shù)對(duì)應(yīng)方式。首先,回憶一下根據(jù)位置傳遞:def f(a,b,c): print a,b,cf(1,2,3)在調(diào)用f時(shí),1,2,3根據(jù)位置分別傳遞給了a,b,c。1. 關(guān)鍵字(keyword)參數(shù)傳遞有時(shí)候,我們發(fā)現(xiàn),在寫程序時(shí)用位置傳遞會(huì)感覺比較死板。關(guān)鍵字傳遞就是根據(jù)每個(gè)參數(shù)的名字傳遞值,而不用遵守固定的位置。依然沿用上面f的定義,更改調(diào)用方式:f(c=3,b=2,a=1)關(guān)鍵字傳遞可以和位置傳遞混用,但位置傳遞的參數(shù)必須在關(guān)鍵字傳遞的參數(shù)之前。f(1,c=3,b=2)2. 參數(shù)默認(rèn)值(default)在定義

11、函數(shù)的時(shí)候,使用形如a=19的方式,可以給參數(shù)賦予默認(rèn)值。如果該參數(shù)最終沒有被傳遞值,將使用該默認(rèn)值。def f(a,b,c=10): print a,b,cf(3,2)f(3,2,1)在第一次調(diào)用函數(shù)f時(shí), 我們并沒有足夠的值,c沒有被賦值,c將使用默認(rèn)值10.第二次調(diào)用函數(shù)的時(shí)候,c被賦值為1,不再使用默認(rèn)值。3. 包裹(packing)位置傳遞和包裹關(guān)鍵字傳遞:在定義函數(shù)時(shí),我們有時(shí)候并不知道調(diào)用的時(shí)候會(huì)傳遞多少個(gè)函數(shù)。這時(shí)候,使用包裹位置傳遞和包裹關(guān)鍵字傳遞會(huì)非常有用。下面是包裹位置傳遞的例子:def func(*name): print type(name) print namefu

12、nc(1,4,6)func(5,6,7,1,2,3)上面的兩次調(diào)用,盡管參數(shù)的個(gè)數(shù)不同,依然可以用同一個(gè)func定義。原因在于,在func的參數(shù)表中,所有的參數(shù)被name收集,根據(jù)位置合并成一個(gè)定值表(tuple),這就是包裹位置傳遞。為了提醒python參數(shù)name是包裹位置傳遞所用的定值表名,在定義func時(shí),在name前加*號(hào)。下面是包裹關(guān)鍵字傳遞的例子:def func(*dict): print type(dict) print dictfunc(a=1,b=9)func(m=2,n=1,c=11)與上面一個(gè)例子類似,dict是一個(gè)字典,收集所有的關(guān)鍵字,傳遞給函數(shù)func。為了提醒

13、python參數(shù)dict是包裹關(guān)鍵字傳遞所用的字典,在dict前加*。我們看到,包裹位置傳遞和包裹關(guān)鍵字傳遞的關(guān)鍵在于定義函數(shù)時(shí),在相應(yīng)定值表或字典前加*或*。4. 解包裹*和*在調(diào)用的時(shí)候的應(yīng)用,主要是解包裹(unpacking), 下面為例:def func(a,b,c): print a,b,cargs = (1,3,4)func(*args)在這個(gè)例子中,所謂的解包裹,就是在傳遞tuple時(shí),讓tuple的每一個(gè)元素對(duì)應(yīng)一個(gè)位置參數(shù)。在這里,通過在調(diào)用func時(shí)使用*,我們提醒python,我想要把a(bǔ)rgs拆成分散的三個(gè)元素,分別傳遞給a,b,c。(設(shè)想一下在調(diào)用func時(shí),args前

14、面沒有*會(huì)是什么后果?)相應(yīng)的,也存在對(duì)詞典的解包裹,使用相同的func定義,然后:dict = a:1,b:2,c:3func(*dict)在傳遞詞典dict時(shí),讓詞典的每個(gè)鍵值對(duì)作為一個(gè)關(guān)鍵字傳遞給func。5. 混合定義與混合調(diào)用參數(shù)的幾種傳遞方式可以混合定義和混合調(diào)用。但在過程中要小心前后順序?;驹瓌t是,先位置,再關(guān)鍵字,再包裹位置,再包裹關(guān)鍵字,并且根據(jù)上面所說的原理細(xì)細(xì)分辨。注意:本講的內(nèi)容,請(qǐng)注意定義時(shí)使用和調(diào)用時(shí)使用的區(qū)分。包裹和解包裹并不是相反操作,而是兩個(gè)相對(duì)獨(dú)立的過程??偨Y(jié):關(guān)鍵字,默認(rèn)值,包裹位置,包裹關(guān)鍵字解包裹Python進(jìn)階05 循環(huán)設(shè)計(jì) 作者:Vamei 出處

15、:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!之前在“循環(huán)”一節(jié),我們已經(jīng)討論了Python最基本的循環(huán)語(yǔ)法。這一節(jié),我們將接觸更加靈活的循環(huán)方式。1. 利用range(), 得到下標(biāo)在Python中,for循環(huán)后的in跟隨一個(gè)序列的話,循環(huán)每次使用的序列元素,而不是序列的下標(biāo)。之前我們已經(jīng)使用過range來控制for循環(huán)?,F(xiàn)在,我們繼續(xù)開發(fā)range的功能,以實(shí)現(xiàn)下標(biāo)對(duì)循環(huán)的控制:S = abcdefghijkfor i in range(0,len(S),2): print Si在該例子中,我們利用len()函數(shù)和range()函數(shù),用i作為S

16、序列的下標(biāo)來控制循環(huán)。在range函數(shù)中,分別定義上限,下限和每次循環(huán)的步長(zhǎng)。這就和C語(yǔ)言中的for循環(huán)相類似了。2. 利用enumerate(), 同時(shí)得到下標(biāo)和元素利用enumerate()函數(shù),可以在每次循環(huán)中同時(shí)得到下標(biāo)和元素:S = abcdefghijkfor (index,char) in enumerate(S): print index print char實(shí)際上,enumerate()在每次循環(huán)中,返回的是一個(gè)包含兩個(gè)元素的定值表(tuple),兩個(gè)元素分別賦予index和char3. 利用zip(), 實(shí)現(xiàn)并行循環(huán)如果你多個(gè)等長(zhǎng)的序列,然后想要每次循環(huán)時(shí)從各個(gè)序列分別取出

17、一個(gè)元素,可以利用zip()方便地實(shí)現(xiàn):ta = 1,2,3tb = 9,8,7tc = a,b,cfor (a,b,c) in zip(ta,tb,tc): print a,b,c實(shí)際上,zip()在每次循環(huán)時(shí),從各個(gè)序列分別從左到右取出一個(gè)元素,合并成一個(gè)tuple,然后tuple的元素賦予給a,b,c總結(jié):range()enumerate()zip()Python進(jìn)階06 循環(huán)對(duì)象 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!通過上面一講,我們?cè)俅问煜ち薖ython里的循環(huán)控制?,F(xiàn)在,我們將接觸循環(huán)對(duì)象(iterabl

18、e object)。這一講的主要目的是為了大家在讀Python程序的時(shí)候?qū)ρh(huán)對(duì)象有一個(gè)基本概念。循環(huán)對(duì)象的并不是隨著Python的誕生就存在的,但它的發(fā)展迅速,特別是Python 3x的時(shí)代,從zip()或者map()的改變來看,循環(huán)對(duì)象正在成為循環(huán)的標(biāo)準(zhǔn)形式。1. 什么是循環(huán)對(duì)象循環(huán)對(duì)象是這樣一個(gè)對(duì)象,它包含有一個(gè)next()方法(_next_()方法,在python 3x中), 這個(gè)方法的目的是進(jìn)行到下一個(gè)結(jié)果,而在結(jié)束一系列結(jié)果之后,舉出StopIteration錯(cuò)誤。當(dāng)一個(gè)循環(huán)結(jié)構(gòu)(比如for)調(diào)用循環(huán)對(duì)象時(shí),它就會(huì)每次循環(huán)的時(shí)候調(diào)用next()方法,直到StopIteration出

19、現(xiàn),for循環(huán)接收到,就知道循環(huán)已經(jīng)結(jié)束,停止調(diào)用next()。假設(shè)我們有一個(gè)test.txt的文件:1234abcdefg我們運(yùn)行一下python命令行: f = open(test.txt) f.next() f.next().不斷地輸入f.next(),直到最后出現(xiàn)StopIterationopen()返回的實(shí)際上是一個(gè)循環(huán)對(duì)象,包含有next()方法。而該next()方法每次返回的就是新的一行的內(nèi)容,到達(dá)文件結(jié)尾時(shí)舉出StopIteration。這樣,我們相當(dāng)于手工進(jìn)行了循環(huán)。自動(dòng)進(jìn)行的話,就是:for line in open(test.txt): print line在這里,for

20、結(jié)構(gòu)自動(dòng)調(diào)用next()方法,將該方法的返回值賦予給line。循環(huán)知道出現(xiàn)StopIteration的時(shí)候結(jié)束。相對(duì)于序列,用循環(huán)對(duì)象來控制循環(huán)的好處在于:可以不用在循環(huán)還沒有開始的時(shí)候,就生成每次要使用的元素。所使用的元素在循環(huán)過程中逐次生成。這樣,就節(jié)省了空間,提高了效率,并提高編程的靈活性。2. iter()函數(shù)和循環(huán)器(iterator)從技術(shù)上來說,循環(huán)對(duì)象和for循環(huán)調(diào)用之間還有一個(gè)中間層,就是要將循環(huán)對(duì)象轉(zhuǎn)換成循環(huán)器(iterator)。這一轉(zhuǎn)換是通過使用iter()函數(shù)實(shí)現(xiàn)的。但從邏輯層面上,常??梢院雎赃@一層,所以循環(huán)對(duì)象和循環(huán)器常常相互指代對(duì)方。3. 生成器(generat

21、or)生成器的主要目的是構(gòu)成一個(gè)用戶自定義的循環(huán)對(duì)象。生成器的編寫方法和函數(shù)定義類似,只是在return的地方改為yield。生成器中可以有多個(gè)yield。當(dāng)生成器遇到一個(gè)yield時(shí),會(huì)暫停運(yùn)行生成器,返回yield后面的值。當(dāng)再次調(diào)用生成器的時(shí)候,會(huì)從剛才暫停的地方繼續(xù)運(yùn)行,直到下一個(gè)yield。生成器自身又構(gòu)成一個(gè)循環(huán)器,每次循環(huán)使用一個(gè)yield返回的值。下面是一個(gè)生成器:def gen(): a = 100 yield a a = a*8 yield a yield 1000該生成器共有三個(gè)yield, 如果用作循環(huán)器時(shí),會(huì)進(jìn)行三次循環(huán)。for i in gen(): print i

22、再考慮如下一個(gè)生成器:def gen(): for i in range(4): yield i它又可以寫成生成器表達(dá)式(Generator Expression):G = (x for x in range(4)生成器表達(dá)式是生成器的一種簡(jiǎn)便的編寫方式。讀者可進(jìn)一步查閱。4. 表理解(list comprehension)表理解是快速生成表的方法。假設(shè)我們生成表L:L = for x in range(10): L.append(x*2)以上產(chǎn)生了表L,但實(shí)際上有快捷的寫法,也就是表理解的方式:L = x*2 for x in range(10)這與生成器表達(dá)式類似,只不過用的是中括號(hào)。(表

23、理解的機(jī)制實(shí)際上是利用循環(huán)對(duì)象,有興趣可以查閱。)考慮下面的表理解會(huì)生成什么?xl = 1,3,5yl = 9,12,13L = x*2 for (x,y) in zip(xl,yl) if y 10總結(jié):循環(huán)對(duì)象生成器表理解Python進(jìn)階07 函數(shù)對(duì)象 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!秉承著一切皆對(duì)象的理念,我們?cè)俅位仡^來看函數(shù)(function)這一結(jié)構(gòu)。函數(shù)實(shí)際上也是一個(gè)對(duì)象。既然是一個(gè)對(duì)象,它也具有屬性(可以使用dir()查詢)。作為對(duì)象,它還可以賦值給其它變量名,或者作為參數(shù)傳遞給其它函數(shù)使用。1.

24、lambda在展開之前,我們先提一下lambda。lambda是一種簡(jiǎn)便的,在同一行中定義函數(shù)的方法,其功能可以完全由def定義實(shí)現(xiàn)。lambda例子如下:func = lambda x,y: x + yprint func(3,4)lambda以及之后的內(nèi)容實(shí)際上生成一個(gè)函數(shù)對(duì)象(也就是函數(shù))。該函數(shù)參數(shù)為x,y,返回值為x+y。該函數(shù)對(duì)象賦值給函數(shù)名func。func的調(diào)用與正常函數(shù)無異。以上定義完全可以寫成以下形式:def func(x, y): return x + y2. 函數(shù)可以作為參數(shù)傳遞函數(shù)可以作為一個(gè)對(duì)象進(jìn)行參數(shù)傳遞。函數(shù)名(比如func)即指向該對(duì)象,不需要括號(hào)。比如說:d

25、ef test(f, a, b): print test print f(a, b)test(func, 3, 5)我們可以看到,test函數(shù)的第一個(gè)參數(shù)f就是一個(gè)函數(shù)對(duì)象。我們將func傳遞給f,那么test中的f()所做的實(shí)際上就是func()所實(shí)現(xiàn)的功能。這樣,我們就大大提高了程序的靈活性。假設(shè)我們有另一個(gè)函數(shù)取代func,就可以使用相同的test函數(shù)了。如下:test(lambda x,y: x*2 + y), 6, 9)思考這句程序的含義。3. map函數(shù)map()是Python的內(nèi)置函數(shù),它的第一個(gè)參數(shù)是一個(gè)函數(shù)對(duì)象。re = map(lambda x: x+3),1,3,5,6)

26、這里,map()有兩個(gè)參數(shù),一個(gè)是lambda所定義的函數(shù)對(duì)象,一個(gè)是包含有多個(gè)元素的表。map()的功能是將函數(shù)對(duì)象依次作用于表的每一個(gè)元素,每次作用的結(jié)果儲(chǔ)存于返回的表re中。map通過讀入的函數(shù)(這里是lambda函數(shù))來操作數(shù)據(jù)(這里“數(shù)據(jù)”是表中的每一個(gè)元素,“操作”是對(duì)每個(gè)數(shù)據(jù)加3)。(注意,在Python 3.X中,map()將每次作用結(jié)果yield出來,形成一個(gè)循環(huán)對(duì)象??梢岳胠ist()函數(shù),將該循環(huán)對(duì)象轉(zhuǎn)換成表)如果作為參數(shù)的函數(shù)對(duì)象有多個(gè)參數(shù),可如下例:re = map(lambda x,y: x+y),1,2,3,6,7,9)map()將每次從兩個(gè)表中分別取出一個(gè)元素

27、,帶入lambda所定義的函數(shù)。(本小節(jié)所使用的lambda也完全可以是def定義的更復(fù)雜的函數(shù))4. filter函數(shù)filter函數(shù)與map函數(shù)類似,也是將作為參數(shù)的函數(shù)對(duì)象作用于表的各個(gè)元素。如果函數(shù)對(duì)象返回的是True,則該次的元素被儲(chǔ)存于返回的表中。filter通過讀入的函數(shù)來篩選數(shù)據(jù)。(同樣,在Python 3.X中,filter返回的不是表,而是循環(huán)對(duì)象。)filter函數(shù)的使用如下例:def func(a): if a 100: return True else: return Falseprint filter(func,10,56,101,500)5. reduce函數(shù)re

28、duce函數(shù)的第一個(gè)參數(shù)也是函數(shù),但有一個(gè)要求,就是這個(gè)函數(shù)自身能接收兩個(gè)參數(shù)。reduce可以累進(jìn)地將函數(shù)作用于各個(gè)參數(shù)。如下例:print reduce(lambda x,y: x+y),1,2,5,7,9)reduce的第一個(gè)參數(shù)是lambda函數(shù),它接收兩個(gè)參數(shù)x,y, 返回x+y。reduce將表中的前兩個(gè)元素(1和2)傳 遞給lambda函數(shù),得到3。該返回值(3)將作為lambda函數(shù)的第一個(gè)參數(shù),而表中的下一個(gè)元素(5)作為lambda函數(shù)的第二個(gè)參數(shù),進(jìn)行下 一次的對(duì)lambda函數(shù)的調(diào)用,得到8。依次調(diào)用lambda函數(shù),每次lambda函數(shù)的第一個(gè)參數(shù)是上一次運(yùn)算結(jié)果,而

29、第二個(gè)參數(shù)為表中的下一個(gè)元 素,直到表中沒有剩余元素。上面例子,相當(dāng)于(1+2)+5)+7)+9(根據(jù)mmufhy的提醒: reduce()函數(shù)在3.0里面不能直接用的,它被定義在了functools包里面,需要引入包,見評(píng)論區(qū))總結(jié):函數(shù)是一個(gè)對(duì)象用lambda定義函數(shù)map()filter()reduce()Python進(jìn)階08 錯(cuò)誤處理 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!在項(xiàng)目開發(fā)中,錯(cuò)誤處理是不可或缺的。錯(cuò)誤處理幫助人們debug,通過更加豐富的信息,讓人們更容易找到bug的所在。錯(cuò)誤處理還可以提高程序的容

30、錯(cuò)性。我們之前在講循環(huán)對(duì)象的時(shí)候,曾提到一個(gè)StopIteration的錯(cuò)誤,該錯(cuò)誤是在循環(huán)對(duì)象窮盡所有元素時(shí)的報(bào)錯(cuò)。我們以它為例,來說明基本的錯(cuò)誤處理。一個(gè)包含錯(cuò)誤的程序:re = iter(range(5)for i in range(100): print re.next()print HaHaHaHa首先,我們定義了一個(gè)循環(huán)對(duì)象re,該循環(huán)對(duì)象將進(jìn)行5次循環(huán),每次使用序列的一個(gè)元素。在隨后的for循環(huán)中,我們手工調(diào)用next()函數(shù)。當(dāng)循環(huán)進(jìn)行到第6次的時(shí)候,re.next()不會(huì)再返回元素,而是舉出(raise)StopIteration的錯(cuò)誤。整個(gè)程序?qū)?huì)中斷。我們可以修改以上錯(cuò)誤

31、程序,直到完美的沒有bug。但另一方面,如果我們?cè)趯懗绦虻臅r(shí)候,知道這里可能犯錯(cuò)以及可能的犯錯(cuò)類型,我們可以針對(duì)該錯(cuò)誤類型定義好”應(yīng)急預(yù)案“。re = iter(range(5)try: for i in range(100): print re.next()except StopIteration: print here is end ,iprint HaHaHaHa在try程序段中,我們放入容易犯錯(cuò)的部分。我們可以跟上except,來說明如果在try部分的語(yǔ)句發(fā)生StopIteration時(shí),程序該做的事情。如果沒有發(fā)生錯(cuò)誤,則except部分被跳過。隨后,程序?qū)⒗^續(xù)運(yùn)行,而不是徹底中斷。

32、完整的語(yǔ)法結(jié)構(gòu)如下:try: .except error1: .except error2: .else: .finally: .else是指所有其它的錯(cuò)誤。finally是無論何種情況,最后都要做的一些事情。流程如下,try-except/else-finally我們也可以自己寫一個(gè)舉出錯(cuò)誤的例子:print Lalalaraise StopIterationprint Hahaha(注意,這個(gè)例子不具備任何實(shí)際意義。讀者可探索更多有意義的例子。)StopIteration是一個(gè)類。當(dāng)我們r(jià)aise它的時(shí)候,有一個(gè)中間環(huán)節(jié),就是Python利用StopIteration生成一個(gè)該類的一個(gè)對(duì)象

33、。Python實(shí)際上舉出的,是這一個(gè)對(duì)象。當(dāng)然,也可以直接寫成:raise StopIteration()總結(jié):try: . except error: . else: . finally: .raise errorPython進(jìn)階09 動(dòng)態(tài)類型 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!謝謝TeaEra, 貓咪cat動(dòng)態(tài)類型(dynamic typing)是Python另一個(gè)重要的核心概念。我們之前說過,Python的變量(variable)不需要聲明,而在賦值時(shí),變量可以重新賦值為任意值。這些都與動(dòng)態(tài)類型的概念相關(guān)。1

34、. 動(dòng)態(tài)類型在我們接觸的對(duì)象中,有一類特殊的對(duì)象,是用于存儲(chǔ)數(shù)據(jù)的。常見的該類對(duì)象包括各種數(shù)字,字符串,表,詞典。在C語(yǔ)言中,我們稱這樣一些數(shù)據(jù)結(jié)構(gòu)為變量。而在Python中,這些是對(duì)象。對(duì)象是儲(chǔ)存在內(nèi)存中的實(shí)體。而我們的變量,實(shí)際上只是指向這一對(duì)象的參考(reference),類似于C語(yǔ)言的指針。(在C語(yǔ)言中,變量自身就是存儲(chǔ)于內(nèi)存中的實(shí)體)變量和它所指的對(duì)象的分離,就是動(dòng)態(tài)類型的核心。由于變量只類似于一個(gè)指針,所以它可以隨時(shí)指向一個(gè)新的對(duì)象,即使這個(gè)新的對(duì)象的類型發(fā)生了變化。a = 3a = at第一個(gè)語(yǔ)句中,3是儲(chǔ)存在內(nèi)存中的一個(gè)整數(shù)對(duì)象。通過賦值,我們將在內(nèi)存中建立這一對(duì)象,并將變量a

35、指向改對(duì)象。第二個(gè)語(yǔ)句中,我們?cè)趦?nèi)存中建立對(duì)象at, 其類型是字符串(string)。變量a在此又指向了at。而此時(shí),對(duì)象3不再有變量指向它,Python會(huì)自動(dòng)將沒有變量指向的對(duì)象銷毀(destruct),從而釋放相應(yīng)內(nèi)存。(對(duì)于小的整數(shù)和短字符串,實(shí)際上Python會(huì)緩存這些對(duì)象,而不是針對(duì)每次賦值而分別建立和銷毀。但從邏輯層面上來說,上面的說法并沒有問題。我們將忽略這一細(xì)節(jié))a = 5b = aa = a + 2再看這個(gè)例子。通過前兩個(gè)句子,我們讓a,b指向同一個(gè)整數(shù)對(duì)象5(b = a的含義是讓變量b指向變量a所指的那一個(gè)對(duì)象)。但第三個(gè)句子實(shí)際上對(duì)變量a重新賦值,讓a指向一個(gè)新的對(duì)象7。

36、此時(shí)a,b分別指向不同的對(duì)象。我們看到,即使是多個(gè)變量指向同一個(gè)對(duì)象,如果一個(gè)變量值發(fā)生變化,那么實(shí)際上是讓這個(gè)變量指向一個(gè)新的變量,并不影響其他的變量的指向。從效果上看,就是各個(gè)變量各自獨(dú)立,互不影響。不止是整數(shù)如此,其它數(shù)據(jù)對(duì)象也是如此:L1 = 1,2,3L2 = L1L1 = 1但注意以下情況L1 = 1,2,3L2 = L1L10 = 10print L2在該情況下,我們不再對(duì)L1這一變量賦值,而是對(duì)L1所指向的表的元素賦值。結(jié)果是,L2也同時(shí)發(fā)生變化。原因何在呢?因?yàn)長(zhǎng)1,L2的指向沒有發(fā)生變 化,依然指向那個(gè)表。表實(shí)際上是包含了多個(gè)變量的對(duì)象(每個(gè)變量是一個(gè)元素,比如L10,L1

37、1., 每個(gè)變量指向一個(gè)對(duì)象,比如1,2,3), 。而L10 = 10這一賦值操作,并不是改變L1的指向,而是對(duì)L10, 也就是表對(duì)象的一部份(一個(gè)元素),進(jìn)行操作,所以所有指向該對(duì)象的變量都受到影響。(與之形成對(duì)比的是,我們之前的賦值操作都沒有對(duì)對(duì)象自身發(fā)生作用,只是改變變量指向。)像表這樣,可以通過引用元素,改變內(nèi)存中的對(duì)象自身(in-place change)的對(duì)象類型,稱為可變數(shù)據(jù)對(duì)象(mutable object),詞典也是這樣的數(shù)據(jù)類型。而像之前的數(shù)字和字符串,不能改變對(duì)象本身,只能改變變量的指向,稱為不可變數(shù)據(jù)對(duì)象(immutable object)。我們之前學(xué)的定值表(tupl

38、e),盡管可以引用引用元素,但不可以通過賦值改變?cè)兀惨虼瞬荒軐?duì)對(duì)象本身進(jìn)行改變,也是immutable object.2. 從動(dòng)態(tài)類型看函數(shù)的參數(shù)傳遞函數(shù)的參數(shù)傳遞,實(shí)際上是讓函數(shù)的各個(gè)參數(shù)作為變量,指向?qū)ο?。比如說:def f(x): x = 100 print xa = 1f(a)print a在調(diào)用函數(shù)f()時(shí),實(shí)際上函數(shù)讓參數(shù)作為一個(gè)變量,指向a所指的對(duì)象。如果參數(shù)是不可變(immutable)的對(duì)象,那么如上面所講,各個(gè)變量之間相當(dāng)于相互獨(dú)立。參數(shù)傳遞類似于C語(yǔ)言中的值傳遞。如果是參數(shù)是可變(mutable)的對(duì)象,那么存在有改變對(duì)象自身的可能性,所有指向該對(duì)象的變量(無論是函數(shù)

39、中的參數(shù),還是主程序中的變量)都會(huì)受影響,編程的時(shí)候要對(duì)此問題留心。比如說:def f(x): x0 = 100 print xa = 1,2,3f(a)print a動(dòng)態(tài)類型是Python的核心機(jī)制之一??梢栽趹?yīng)用中慢慢熟悉。總結(jié):變量和對(duì)象的分離,對(duì)象是內(nèi)存中儲(chǔ)存數(shù)據(jù)的實(shí)體,變量指向?qū)ο蟆?勺儗?duì)象,不可變對(duì)象函數(shù)值傳遞Python快速教程總結(jié) 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!到現(xiàn)在為止,Python快速教程就到一段落。謝謝大家的鼓勵(lì)和支持,特別是對(duì)其中錯(cuò)誤的包容和指正。在第一部分,基礎(chǔ)部分中,除了一些基礎(chǔ)知識(shí)

40、,我們著力于建立對(duì)象的概念。在第二部分中,我們深入到許多實(shí)用并且常用的Python用法。如果只是想 了解Python是什么,那么第一部分應(yīng)該可以給出一個(gè)基本概念。加上第二部分的話,我們應(yīng)該可以有足夠的知識(shí)讀懂Python程序,并編寫一些應(yīng)用。我會(huì)在以后寫一些選讀性的隨筆,以便對(duì)教程更進(jìn)一步補(bǔ)充。我還在考慮下一步在博客中寫什么。Python依然有一個(gè)龐大的標(biāo)準(zhǔn)庫(kù)可以展開。但標(biāo)準(zhǔn)庫(kù)的講解離不開對(duì)計(jì)算機(jī)原理和互聯(lián)網(wǎng)原理的了解,很難以一個(gè) 快速教程的方式呈現(xiàn)出來。但離開標(biāo)準(zhǔn)庫(kù),Python也顯得很單薄。一個(gè)可能是,先寫一個(gè)總體綱要,描述一下標(biāo)準(zhǔn)庫(kù)各個(gè)包所包含的內(nèi)容,以及可能的用途, 不知是否可行?另外

41、,最近看了一些Google Engine和Django的內(nèi)容,覺得也不錯(cuò)。只可惜自己在這方面經(jīng)驗(yàn)太淺,不知從何說起。另一方面,我個(gè)人的Python經(jīng)驗(yàn)也非常有限。希望能多參與到一些項(xiàng)目,以便能積累經(jīng)驗(yàn)??傊?,休息,休息一下。Python補(bǔ)充01 序列的方法 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!在快速教程中,我們了解了最基本的序列(sequence)?;貞浺幌拢蛄邪卸ㄖ当?tuple)和表(list)。此外,字符串(string)是一種特殊的定值表。表的元素可以更改,定值表一旦建立,其元素不可更改。任何的序列都可

42、以引用其中的元素(item)。下面的內(nèi)建函數(shù)(built-in function)可用于序列(表,定值表,字符串):# s為一個(gè)序列l(wèi)en(s) 返回: 序列中包含元素的個(gè)數(shù)min(s) 返回: 序列中最小的元素max(s) 返回: 序列中最大的元素all(s) 返回: True, 如果所有元素都為True的話any(s) 返回: True, 如果任一元素為True的話下面的方法主要起查詢功能,不改變序列本身, 可用于表和定值表:sum(s) 返回:序列中所有元素的和# x為元素值,i為下標(biāo)(元素在序列中的位置)s.count(x) 返回: x在s中出現(xiàn)的次數(shù)s.index(x) 返回: x在

43、s中第一次出現(xiàn)的下標(biāo)由于定值表的元素不可變更,下面方法只適用于表:# l為一個(gè)表, l2為另一個(gè)表l.extend(l2) 在表l的末尾添加表l2的所有元素l.append(x) 在l的末尾附加x元素l.sort() 對(duì)l中的元素排序l.reverse() 將l中的元素逆序l.pop() 返回:表l的最后一個(gè)元素,并在表l中刪除該元素del li 刪除該元素(以上這些方法都是在原來的表的上進(jìn)行操作,會(huì)對(duì)原來的表產(chǎn)生影響,而不是返回一個(gè)新表。)下面是一些用于字符串的方法。盡管字符串是定值表的特殊的一種,但字符串(string)類有一些方法是改變字符串的。這些方法的本質(zhì)不是對(duì)原有字符串進(jìn)行操作,而

44、是刪除原有字符串,再建立一個(gè)新的字符串,所以并不與定值表的特點(diǎn)相矛盾。#str為一個(gè)字符串,sub為str的一個(gè)子字符串。s為一個(gè)序列,它的元素都是字符串。width為一個(gè)整數(shù),用于說明新生成字符串的寬度。str.count(sub) 返回:sub在str中出現(xiàn)的次數(shù)str.find(sub) 返回:從左開始,查找sub在str中第一次出現(xiàn)的位置。如果str中不包含sub,返回 -1str.index(sub) 返回:從左開始,查找sub在str中第一次出現(xiàn)的位置。如果str中不包含sub,舉出錯(cuò)誤str.rfind(sub) 返回:從右開始,查找sub在str中第一次出現(xiàn)的位置。如果str中

45、不包含sub,返回 -1str.rindex(sub) 返回:從右開始,查找sub在str中第一次出現(xiàn)的位置。如果str中不包含sub,舉出錯(cuò)誤str.isalnum() 返回:True, 如果所有的字符都是字母或數(shù)字str.isalpha() 返回:True,如果所有的字符都是字母str.isdigit() 返回:True,如果所有的字符都是數(shù)字str.istitle() 返回:True,如果所有的詞的首字母都是大寫str.isspace() 返回:True,如果所有的字符都是空格str.islower() 返回:True,如果所有的字符都是小寫字母str.isupper() 返回:True

46、,如果所有的字符都是大寫字母str.split(sep, max) 返回:從左開始,以空格為分割符(separator),將str分割為多個(gè)子字符串,總共分割max次。將所得的子字符串放在一個(gè)表中返回??梢詓tr.split(,)的方式使用逗號(hào)或者其它分割符str.rsplit(sep, max) 返回:從右開始,以空格為分割符(separator),將str分割為多個(gè)子字符串,總共分割max次。將所得的子字符串放在一個(gè)表中返回??梢詓tr.rsplit(,)的方式使用逗號(hào)或者其它分割符str.join(s) 返回:將s中的元素,以str為分割符,合并成為一個(gè)字符串。str.strip(sub

47、) 返回:去掉字符串開頭和結(jié)尾的空格。也可以提供參數(shù)sub,去掉位于字符串開頭和結(jié)尾的sub str.replace(sub, new_sub) 返回:用一個(gè)新的字符串new_sub替換str中的sub str.capitalize() 返回:將str第一個(gè)字母大寫str.lower() 返回:將str全部字母改為小寫str.upper() 返回:將str全部字母改為大寫str.swapcase() 返回:將str大寫字母改為小寫,小寫改為大寫str.title() 返回:將str的每個(gè)詞(以空格分隔)的首字母大寫str.center(width) 返回:長(zhǎng)度為width的字符串,將原字符串放

48、入該字符串中心,其它空余位置為空格。str.ljust(width) 返回:長(zhǎng)度為width的字符串,將原字符串左對(duì)齊放入該字符串,其它空余位置為空格。str.rjust(width) 返回:長(zhǎng)度為width的字符串,將原字符串右對(duì)齊放入該字符串,其它空余位置為空格。Python補(bǔ)充02 我的Python小技巧 作者:Vamei 出處:/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝!在這里列舉一些我使用Python時(shí)積累的小技巧。這些技巧是我在使用Python過程中經(jīng)常使用的。之前很零碎的記在筆記本中,現(xiàn)在整理出來,和大家分享,也作為Python快速教

49、程的一個(gè)補(bǔ)充。import模塊在Python經(jīng)常使用import聲明,以使用其他模塊(也就是其它.py文件)中定義的對(duì)象。1) 使用_name_當(dāng)我們編寫Python庫(kù)模塊的時(shí)候,我們往往運(yùn)行一些測(cè)試語(yǔ)句。當(dāng)這個(gè)程序作為庫(kù)被import的時(shí)候,我們并不需要運(yùn)行這些測(cè)試語(yǔ)句。一種解決方法是在import之前,將模塊中的測(cè)試語(yǔ)句注釋掉。Python有一種更優(yōu)美的解決方法,就是使用_name_。下面是一個(gè)簡(jiǎn)單的庫(kù)程序TestLib.py。當(dāng)直接運(yùn)行TestLib.py時(shí),_name_為_main_。如果被import的話,_name_為TestLib。def lib_func(a): return

50、a + 10def lib_func_another(b): return b + 20if _name_ = _main_: test = 101 print(lib_func(test)我們?cè)趗ser.py中import上面的TestLib。import TestLibprint(TestLib.lib_func(120)你可以嘗試不在TestLib.py中使用if _name_=_main_, 并對(duì)比運(yùn)行結(jié)果。2) 更多import使用方式import TestLib as test # 引用TestLib模塊,并將它改名為t比如:import TestLib as tprint(t.l

51、ib_func(120)from TestLib import lib_func # 只引用TestLib中的lib_func對(duì)象,并跳過TestLib引用字段這樣的好處是減小所引用模塊的內(nèi)存占用。比如:from TestLib import lib_funcprint(lib_func(120)from TestLib import * # 引用所有TestLib中的對(duì)象,并跳過TestLib引用字段比如:from TestLib import *print(lib_func(120)查詢1) 查詢函數(shù)的參數(shù)當(dāng)我們想要知道某個(gè)函數(shù)會(huì)接收哪些參數(shù)的時(shí)候,可以使用下面方法查詢。import in

52、spectprint(inspect.getargspec(func)2) 查詢對(duì)象的屬性除了使用dir()來查詢對(duì)象的屬性之外,我們可以使用下面內(nèi)置(built-in)函數(shù)來確認(rèn)一個(gè)對(duì)象是否具有某個(gè)屬性:hasattr(obj, attr_name) # attr_name是一個(gè)字符串例如:a = 1,2,3print(hasattr(a,append)2) 查詢對(duì)象所屬的類和類名稱a = 1, 2, 3print a._class_print a._class_._name_3) 查詢父類我們可以用_base_屬性來查詢某個(gè)類的父類:cls._base_例如:print(list._base_)使用中文(以及其它非ASCII編碼)在Python程序的第一行加入#coding=utf8,例如:#coding=

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論