Python編程基礎(chǔ)(第3版)(微課版)課件 單元5-10 函數(shù)- 綜合案例:汽車銷售數(shù)據(jù) 分析_第1頁
Python編程基礎(chǔ)(第3版)(微課版)課件 單元5-10 函數(shù)- 綜合案例:汽車銷售數(shù)據(jù) 分析_第2頁
Python編程基礎(chǔ)(第3版)(微課版)課件 單元5-10 函數(shù)- 綜合案例:汽車銷售數(shù)據(jù) 分析_第3頁
Python編程基礎(chǔ)(第3版)(微課版)課件 單元5-10 函數(shù)- 綜合案例:汽車銷售數(shù)據(jù) 分析_第4頁
Python編程基礎(chǔ)(第3版)(微課版)課件 單元5-10 函數(shù)- 綜合案例:汽車銷售數(shù)據(jù) 分析_第5頁
已閱讀5頁,還剩337頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

自定義函數(shù)1區(qū)分局部變量和全局變量目錄嵌套函數(shù)2【任務(wù)5-1】構(gòu)建計算用餐總價格的函數(shù)3【任務(wù)5-2】構(gòu)建求方差函數(shù)4Python允許在函數(shù)內(nèi)部定義另外一個函數(shù),即嵌套函數(shù)。定義在其他函數(shù)內(nèi)部的函數(shù)稱為內(nèi)置函數(shù),而包含內(nèi)置函數(shù)的函數(shù)稱為外部函數(shù)。內(nèi)置函數(shù)中的局部變量獨立于外部函數(shù),如果外部函數(shù)想要使用這些變量,那么需要聲明相應(yīng)變量為全局變量。嵌套函數(shù)>>>defmean(*args):#定義求均值函數(shù)...m=0...defsum(x):#內(nèi)建求和函數(shù)...sum1=0...foriinx:...sum1+=i...returnsum1...m=sum(args)/len(args)...returnm嵌套函數(shù)如果需要定義一個求均值的函數(shù),那么需要先計算數(shù)值的和,可以在求均值函數(shù)的內(nèi)部內(nèi)建求和函數(shù),示例代碼如下。Python也將函數(shù)視為對象,因此允許外部函數(shù)在返回結(jié)果時直接調(diào)用內(nèi)置函數(shù)的結(jié)果。如下代碼示例,可以簡化求均值函數(shù),令其直接返回求和函數(shù)的結(jié)果。嵌套函數(shù)>>>defmeans(*args):...defsum(x):...sum1=0...foriinx:...sum1+=i...returnsum1...returnsum(args)/len(args)#直接返回求和函數(shù)的結(jié)果1區(qū)分局部變量和全局變量目錄嵌套函數(shù)2【任務(wù)5-1】構(gòu)建計算用餐總價格的函數(shù)3【任務(wù)5-2】構(gòu)建求方差函數(shù)4定義函數(shù)時往往需要在函數(shù)內(nèi)部對變量進行定義和賦值,在函數(shù)內(nèi)部定義的變量即局部變量。例如,定義一個求和函數(shù),代碼如下。1.局部變量>>>defsum(*arg):...sum1=0...foriinrange(len(arg)):...sum1+=arg[i]...returnsum1>>>print(sum(1,2,3,4,5))15>>>print(sum1)NameError:name'sum1'isnotdefined與局部變量對應(yīng),定義在函數(shù)外部的變量即全局變量。全局變量可以在函數(shù)內(nèi)部被調(diào)用,代碼如下。2.全局變量>>>sum0=10>>>deffun():...sum_global=sum0+100...returnsum_global>>>print(fun())110全局變量不能在函數(shù)內(nèi)部直接被賦值,否則會報錯,代碼如下。2.全局變量>>>sum1=0>>>defsum(*arg):...foriinrange(len(arg)):...sum1+=arg[i]...returnsum1>>>print(sum(1,2,3,4))UnboundLocalError:cannotaccesslocalvariable'sum1'whereitisnotassociatedwithavalue若同時存在全局變量和局部變量,則函數(shù)會使用局部變量對全局變量進行覆蓋,代碼如下。2.全局變量>>>sum1=10>>>defsum(*arg):...sum1=0...foriinrange(len(arg)):...sum1+=arg[i]...returnsum1>>>print(sum(1,3,4,5))13如果想要在函數(shù)內(nèi)部對全局變量賦值,那么需要使用關(guān)鍵字global。在嵌套函數(shù)中,nonlocal的用法和global類似,示例代碼如下。2.全局變量>>>sum1=0>>>defsum(*arg):...globalsum1...foriinrange(len(arg)):...sum1+=arg[i]...returnsum1>>>print(sum(1,3,5,7))16>>>print(sum1)16>>>print(sum(1,3,5,7))321區(qū)分局部變量和全局變量目錄嵌套函數(shù)2【任務(wù)5-1】構(gòu)建計算用餐總價格的函數(shù)3【任務(wù)5-2】構(gòu)建求方差函數(shù)4【任務(wù)5-1】構(gòu)建計算用餐總價格的函數(shù)任務(wù)分析任務(wù)描述為了提高結(jié)賬效率并確保交易準確性,收銀員創(chuàng)建了一個名為day_income的函數(shù),該函數(shù)能夠根據(jù)顧客購買的菜品重量和單價自動計算出總銷售額。(1)創(chuàng)建函數(shù)day_income,輸入?yún)?shù)為菜的單價unit_price和不定參數(shù)客人的點菜重量列表table_count。(2)使用sum函數(shù)計算今日所賣的葷素菜總量。(3)計算當(dāng)日銷售額(菜的重量×菜的單價),并返回當(dāng)日銷售額。(4)調(diào)用函數(shù)day_income,指定當(dāng)日點菜重量列表為[12,9,7,10,7,6,11,9,8,11],菜的單價為10,輸出當(dāng)日銷售額。1區(qū)分局部變量和全局變量目錄嵌套函數(shù)2【任務(wù)5-1】構(gòu)建計算用餐總價格的函數(shù)3【任務(wù)5-2】構(gòu)建求方差函數(shù)4【任務(wù)5-2】構(gòu)建求方差函數(shù)任務(wù)分析任務(wù)描述方差是統(tǒng)計學(xué)中用于衡量數(shù)據(jù)波動性的關(guān)鍵指標(biāo),它反映了數(shù)據(jù)與平均值之間的差異。根據(jù)函數(shù)構(gòu)建求方差的函數(shù)。(1)構(gòu)建求和函數(shù)sum。(2)構(gòu)建求均值函數(shù)mean,需調(diào)用求和函數(shù)sum的結(jié)果。(3)構(gòu)建求完全平方差函數(shù)sums,需調(diào)用求均值函數(shù)mean的結(jié)果。(4)構(gòu)建求方差函數(shù)var,構(gòu)建sum函數(shù)、mean函數(shù)和sums函數(shù),并需調(diào)用求完全平方差函數(shù)sums的結(jié)果。自定義函數(shù)1設(shè)置函數(shù)參數(shù)目錄認識自定義函數(shù)2函數(shù)返回值3調(diào)用自定義函數(shù)4Python提供了自定義函數(shù)的功能。使用def關(guān)鍵字可以自定義函數(shù),格式如下。認識自定義函數(shù)deffunction(par1,par2,…):suitereturnexpression其中function為函數(shù)名,括號內(nèi)包含將要在函數(shù)體中使用的形式參數(shù)(簡稱形參),定義語句以冒號結(jié)束;suite為函數(shù)體,其縮進為4個空格或一個制表符;expression為返回值的表達式。函數(shù)定義示例如代碼如下。認識自定義函數(shù)>>>defmy_function(parameter):#輸出傳入的任何字符串...print(parameter)#print與return沒有關(guān)系,也不會相互影響...return'parameteris'+parameter函數(shù)名為my_function,輸入?yún)?shù)是parameter,輸出參數(shù)是parameter,返回值是“parameteris”字符串加上parameter參數(shù)。1設(shè)置函數(shù)參數(shù)目錄認識自定義函數(shù)2函數(shù)返回值3調(diào)用自定義函數(shù)4在Python中,函數(shù)參數(shù)主要有以下4種。(1)位置參數(shù)。調(diào)用函數(shù)時,根據(jù)函數(shù)定義的位置參數(shù)來傳遞參數(shù)。(2)關(guān)鍵字參數(shù)。關(guān)鍵字參數(shù)通過“鍵-值”形式加以指定,可以讓函數(shù)更加清晰、容易使用,同時也消除了參數(shù)的順序要求。(3)默認參數(shù)。定義函數(shù)時為參數(shù)提供了默認值的參數(shù)稱為默認參數(shù)。在調(diào)用函數(shù)時,默認參數(shù)的值可傳可不傳。需要注意的是,所有的位置參數(shù)必須出現(xiàn)在默認參數(shù)前。(4)可變參數(shù)。當(dāng)定義函數(shù)時,有時候不確定之后調(diào)用時會傳遞多少個參數(shù)(也可以不傳參數(shù))。此時,可使用定義任意位置參數(shù)或關(guān)鍵字參數(shù)的方法來進行參數(shù)傳遞。設(shè)置函數(shù)參數(shù)在調(diào)用內(nèi)置函數(shù)時,函數(shù)提供了默認參數(shù)。下面定義一個計算利息的函數(shù),示例如下。1.默認參數(shù)>>>definterest(money,day=1,interest_rate=0.05):...income=money*interest_rate*day/365...print(income)當(dāng)僅需要計算單日利息時,只需要輸入本金的數(shù)值即可,示例如下。>>>print(interest(5000))#本金為5000,年化利率為默認值0.05時的單日利息0.684931506849315>>>print(interest(10000))#本金為10000,年化利率為默認值0.05時的單日利息1.36986301369863定義函數(shù)時需要確定函數(shù)的參數(shù)個數(shù),參數(shù)個數(shù)表示函數(shù)可調(diào)用的參數(shù)個數(shù)的上限。當(dāng)定義函數(shù)時,如果無法確定參數(shù)個數(shù),可以使用*args和**kwargs定義可變參數(shù)。在定義任意數(shù)量的位置可變參數(shù)時,參數(shù)名前面需要有一個星號(*)作為前綴,在傳遞參數(shù)的時候,可以在原有的參數(shù)后面添加0個或多個參數(shù),這些參數(shù)將會被放在元組中并傳入函數(shù)。任意數(shù)量的位置可變參數(shù)必須定義在位置參數(shù)或關(guān)鍵字參數(shù)之后,示例代碼如下。2.任意數(shù)量的位置可變參數(shù)>>>defexp(x,y,*args):...print('x:',x)...print('y:',y)...print('args:',args)>>>exp(1,5,66,55,'abc')x:1y:5args:(66,55,'abc')2.任意數(shù)量的位置可變參數(shù)在定義任意數(shù)量的關(guān)鍵字可變參數(shù)時,參數(shù)名前面需要有兩個星號(**)作為前綴。在傳遞參數(shù)時,可以在原有的參數(shù)后面添加任意數(shù)量的關(guān)鍵字可變參數(shù),這些參數(shù)會被放到字典中并傳入函數(shù),示例代碼如下。任意數(shù)量的關(guān)鍵字可變參數(shù)必須在所有默認參數(shù)之后,順序不可以調(diào)轉(zhuǎn)。3.任意數(shù)量的關(guān)鍵字可變參數(shù)3.任意數(shù)量的關(guān)鍵字可變參數(shù)>>>defexp(x,y,*args,**kwargs):...print('x:',x)...print('y:',y)...print('args:',args)...print('kwargs:',kwargs)>>>exp(1,2,2,4,6,a='c',b=1)x:1y:2args:(2,4,6)kwargs:{'a':'c','b':1}1設(shè)置函數(shù)參數(shù)目錄認識自定義函數(shù)2函數(shù)返回值3調(diào)用自定義函數(shù)4函數(shù)可以處理一些數(shù)據(jù),并返回一個或一組值。函數(shù)返回的值稱為返回值。需要保存或調(diào)用函數(shù)的返回值,那么需要使用return語句,示例代碼如下。函數(shù)返回值>>>definterest_r(money,day=1,interest_rate=0.05):...income=money*interest_rate*day/365...returnincome函數(shù)返回值print函數(shù)僅輸出對象,輸出的對象無法保存或被調(diào)用,而return語句返回的運行結(jié)果可以保存為一個對象供其他函數(shù)調(diào)用,示例代碼如下。>>>x=interest(1000)0.136986301369863>>>y=interest_r(1000)>>>print(y)0.136986301369863Python對函數(shù)返回值的數(shù)據(jù)結(jié)構(gòu)沒有限制,包括列表和字典等復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。當(dāng)程序執(zhí)行到函數(shù)中的return語句時,會將指定的值返回并結(jié)束函數(shù),return語句后面的語句將不會被執(zhí)行。1設(shè)置函數(shù)參數(shù)目錄認識自定義函數(shù)2函數(shù)返回值3調(diào)用自定義函數(shù)4位置參數(shù)調(diào)用是最常用的函數(shù)調(diào)用方式,函數(shù)的參數(shù)嚴格按照函數(shù)定義時的位置傳入,順序不可以調(diào)換,否則會影響輸出結(jié)果或直接報錯。例如,range函數(shù)定義的3個參數(shù)start、stop、step需按照順序傳入,示例代碼如下:1.位置參數(shù)調(diào)用>>>print(list(range(0,10,2)))#按start=0、stop=10、step=2的順序傳入[0,2,4,6,8]>>>print(list(range(10,0,2)))#調(diào)換start和stop的順序后傳入[]>>>print(list(range(10,2,0)))#調(diào)換全部參數(shù)的順序后傳入ValueError:range()arg3mustnotbezero當(dāng)函數(shù)的參數(shù)有默認值時,可以不設(shè)置相應(yīng)的函數(shù)參數(shù),因為此時的函數(shù)會使用默認參數(shù),代碼如下。1.位置參數(shù)調(diào)用>>>print(list(range(0,10,1)))[0,1,2,3,4,5,6,7,8,9]>>>print(list(range(10)))[0,1,2,3,4,5,6,7,8,9]除了可以使用位置參數(shù)對函數(shù)進行調(diào)用外,還可以使用關(guān)鍵字參數(shù)對函數(shù)進行調(diào)用。當(dāng)使用關(guān)鍵字參數(shù)時,可以不嚴格按照定義參數(shù)時參數(shù)的順序傳入值,因為解釋器會自動根據(jù)關(guān)鍵字進行匹配,示例代碼如下。2.關(guān)鍵字參數(shù)調(diào)用>>>print(interest(money=5000,day=7,interest_rate=0.06))5.7534246575342465>>>print(interest(day=7,money=5000,interest_rate=0.06))5.7534246575342465關(guān)鍵字參數(shù)也可以與位置參數(shù)混用。關(guān)鍵字參數(shù)必須跟在位置參數(shù)后面,否則會報錯,示例代碼如下。2.關(guān)鍵字參數(shù)調(diào)用>>>print(interest(10000,day=7,interest_rate=0.06))11.506849315068493>>>print(interest(10000,interest_rate=0.06,day=7))11.506849315068493>>>#關(guān)鍵字參數(shù)必須跟在位置參數(shù)后面,否則會報錯>>>print(interest(interest_rate=0.06,7,money=10000))SyntaxError:positionalargumentfollowskeywordargument使用*args位置可變參數(shù)可以直接將元組或列表轉(zhuǎn)換為參數(shù),然后傳入函數(shù),示例代碼如下。3.可變參數(shù)調(diào)用>>>args=[0,10,2]>>>print(list(range(*args)))[0,2,4,6,8]3.可變參數(shù)調(diào)用使用**kwargs關(guān)鍵字可變參數(shù)可以直接將字典轉(zhuǎn)換為關(guān)鍵字參數(shù),然后傳入函數(shù)中,示例代碼如下。>>>defuser(username,age,**kwargs):...print('username:',username,...'age:',age,...'other:',kwargs)>>>user('john',27,city='guangzhou',job='DataAnalyst')username:johnage:27other:{'city':'guangzhou','job':'DataAnalyst'}>>>kw={'age':27,'city':'guangzhou','job':'DataAnalyst'}>>>user('john',**kw)username:johnage:27other:{'city':'guangzhou','job':'DataAnalyst'}匿名函數(shù)1其他常用高階內(nèi)置函數(shù)目錄創(chuàng)建并使用匿名函數(shù)2【任務(wù)5-3】多種方式實現(xiàn)數(shù)據(jù)累加3匿名函數(shù)是指不使用def語句這樣標(biāo)準的形式定義一個函數(shù),也就是說函數(shù)沒有具體的名稱。使用lambda函數(shù)創(chuàng)建匿名函數(shù)可以省去定義函數(shù)的過程,同時可以避免函數(shù)的重復(fù)使用。在lambda函數(shù)中,冒號前是函數(shù)參數(shù),若有多個參數(shù),需使用逗號分隔;冒號后是返回值。使用lambda函數(shù)創(chuàng)建的函數(shù)沒有具體的名稱。創(chuàng)建函數(shù)的示例如下。創(chuàng)建并使用匿名函數(shù)>>>example=lambdax:x**3>>>print(example)<function<lambda>at0x0000000029E2DD30>>>>print(example(2))8用lambda函數(shù)創(chuàng)建函數(shù)時,應(yīng)該注意以下4點。(1)lambda函數(shù)創(chuàng)建的是單行函數(shù),如果需要創(chuàng)建復(fù)雜的函數(shù),應(yīng)使用def關(guān)鍵字。(2)lambda函數(shù)可以包含多個參數(shù)。(3)lambda函數(shù)有且只有一個返回值。(4)lambda函數(shù)中的表達式不能含有命令,且僅限一個表達式。這是為了避免匿名函數(shù)的濫用,過于復(fù)雜的匿名函數(shù)反而不易于解讀。創(chuàng)建并使用匿名函數(shù)Python允許將lambda函數(shù)作為對象賦值給變量,然后使用變量名進行調(diào)用。例如,在Python的數(shù)學(xué)庫中只有以自然數(shù)e和10為底的對數(shù)函數(shù),而使用lambda函數(shù)即可創(chuàng)建以指定數(shù)為底的對數(shù)函數(shù),示例代碼如下。創(chuàng)建并使用匿名函數(shù)>>>frommathimportlog#引入Python數(shù)學(xué)庫的對數(shù)函數(shù)>>>#此函數(shù)用于返回一個以base為底的匿名對數(shù)函數(shù)>>>defmake_logarithmic_function(base):...returnlambdax:log(x,base)>>>#創(chuàng)建一個以3為底的匿名對數(shù)函數(shù),并賦值>>>my_log=make_logarithmic_function(3)>>>#調(diào)用匿名對數(shù)函數(shù)my_log,底數(shù)已經(jīng)設(shè)置為3,只需設(shè)置真數(shù)即可>>>#如果使用log函數(shù),那么需要同時設(shè)置真數(shù)和底數(shù)>>>print(my_log(9))2.01其他常用高階內(nèi)置函數(shù)目錄創(chuàng)建并使用匿名函數(shù)2【任務(wù)5-3】多種方式實現(xiàn)數(shù)據(jù)累加3map函數(shù)是Python內(nèi)置的高階函數(shù),它的基本格式為map(func,list)。其中,func表示一個函數(shù),list表示一個序列對象。在執(zhí)行的時候,map函數(shù)把函數(shù)func按照從左到右的順序依次作用在list的每個元素上,得到一個新的序列對象并返回。示例代碼如下。1.map函數(shù)>>>defadd(x):...x**=3...returnx>>>numbers=list(range(10))>>>num1=list(map(add,numbers))>>>num2=list(map(lambdax:x**3,numbers))#速度快,可讀性高fib函數(shù)是一個遞歸函數(shù),最典型的遞歸示例之一是斐波那契數(shù)列。根據(jù)斐波那契數(shù)列的定義,可以直接寫出斐波那契數(shù)列遞歸函數(shù)。fib函數(shù)示例代碼如下。2.fib函數(shù)>>>deffib(n):...ifn<=2:...return2...else:...returnfib(n-1)+fib(n-2)>>>f=fib(10)>>>print(f)110在上述代碼中,“fib(n1)+fib(n2)”是調(diào)用了fib函數(shù)自身而實現(xiàn)遞歸的。為了明確遞歸的過程,介紹其計算過程如下(令n=3)。(1)n=3,調(diào)用fib(3),判斷后需計算fib(31)+fib(32)。(2)先看fib(31),即fib(2),返回結(jié)果為2。(3)再看fib(32),即fib(1),返回結(jié)果也為2。(4)最后計算第(1)步,結(jié)果為fib(n1)+fib(n2)=2+2=4,將結(jié)果返回。從而得到fib(3)的結(jié)果為4。從計算過程可以看出,每個遞歸的步驟都是向著最初的已知條件方向得到結(jié)果,然后一層層向上反饋計算結(jié)果。2.fib函數(shù)filter函數(shù)是Python內(nèi)置的另一個常用的高階函數(shù)。filter函數(shù)接收一個函數(shù)func和一個序列對象list,函數(shù)func的作用是對list中的每個元素進行判斷,通過返回True或False來過濾掉不符合條件的元素,將符合條件的元素組成新的序列對象。filter函數(shù)示例代碼如下。3.filter函數(shù)>>>print(list(filter(lambdax:x%2==1,[1,4,6,7,9,12,17])))[1,7,9,17]>>>s=list(filter(lambdac:c!='o','IlovepythonandR!'))>>>s=''.join(s)#轉(zhuǎn)換為字符型>>>print(s)IlovepythonandR!1其他常用高階內(nèi)置函數(shù)目錄創(chuàng)建并使用匿名函數(shù)2【任務(wù)5-3】多種方式實現(xiàn)數(shù)據(jù)累加3【任務(wù)5-3】多種方式實現(xiàn)數(shù)據(jù)累加任務(wù)分析任務(wù)描述分別通過自定義函數(shù)、匿名函數(shù)和map函數(shù)實現(xiàn)一組數(shù)據(jù)的累加。(1)使用def關(guān)鍵字定義一個累加函數(shù)add。(2)創(chuàng)建一個空列表。(3)使用循環(huán)結(jié)構(gòu)foriinrange(10)對列表進行數(shù)據(jù)累加后的元素添加(list.append())。(4)使用匿名函數(shù)代替累加函數(shù),并將計算結(jié)果添加至列表。(5)使用map函數(shù)快速實現(xiàn)數(shù)據(jù)的累加,以及列表元素的添加。存儲并導(dǎo)入函數(shù)模塊1導(dǎo)入函數(shù)目錄存儲并導(dǎo)入整個模塊2指定別名3【任務(wù)5-4】實現(xiàn)求方差函數(shù)存儲與導(dǎo)入4模塊是最高級別的程序組織單元,它能夠?qū)⒊绦虼a和數(shù)據(jù)封裝起來以便重用。模塊通常對應(yīng)Python的腳本文件(.py文件),該文件包含該模塊定義的所有函數(shù)和變量。模塊可以被其他程序?qū)耄员愠绦蚴褂闷渲械暮瘮?shù)等功能。導(dǎo)入模塊后,在模塊文件中定義的所有變量名都會以被導(dǎo)入模塊對象的成員的形式被調(diào)用。存儲并導(dǎo)入整個模塊>>>defmake_steak(d,*other):...'''做一份牛排'''...print('Makeasteakwelldonein%d'%d+'withtheother:')...foroinother:...print('-'+o)存儲并導(dǎo)入整個模塊如果要導(dǎo)入模塊中的函數(shù),那么需要先創(chuàng)建一個模塊。創(chuàng)建一個包含make_steak函數(shù)的模塊,代碼如下。將上述代碼塊保存為steak.py,并存放在當(dāng)前路徑。導(dǎo)入這個模塊,并且調(diào)用里面的make_steak函數(shù),代碼如下。存儲并導(dǎo)入整個模塊>>>importsteak>>>steak.make_steak(9,'salad')Makeasteakwelldonein9withtheother:-salad1導(dǎo)入函數(shù)目錄存儲并導(dǎo)入整個模塊2指定別名3【任務(wù)5-4】實現(xiàn)求方差函數(shù)存儲與導(dǎo)入4在Python中,可以導(dǎo)入模塊中的指定函數(shù),且指定函數(shù)可以是多個。以steak.py為例,只導(dǎo)入指定函數(shù)的操作代碼如下。1.導(dǎo)入指定函數(shù)>>>fromsteakimportmake_steak>>>make_steak(9,'salad')Makeasteakwelldonein9withtheother:-salad如果模塊中的函數(shù)較多,并需要導(dǎo)入所有函數(shù),那么可以使用星號運算符導(dǎo)入所有函數(shù),代碼如下。2.導(dǎo)入所有函數(shù)>>>fromsteakimport*>>>make_steak(9,'salad')Makeasteakwelldonein9withtheother:-salad1導(dǎo)入函數(shù)目錄存儲并導(dǎo)入整個模塊2指定別名3【任務(wù)5-4】實現(xiàn)求方差函數(shù)存儲與導(dǎo)入4如果導(dǎo)入的函數(shù)的名稱可能與程序中現(xiàn)有的名稱沖突或名稱太長,那么可以用as語句在導(dǎo)入時給函數(shù)指定別名。給make_steak函數(shù)指定別名為ms的操作代碼如下。1.指定函數(shù)別名>>>fromsteakimportmake_steakasms>>>ms(9,'salad')Makeasteakwelldonein9withtheother:-salad在Python中,可以給模塊指定別名。通過給模塊指定簡短的別名(如給steak模塊指定別名S),能夠方便地調(diào)用模塊中的函數(shù)。相比類似steak.make_steak的調(diào)用方式更為簡潔,指定模塊別名代碼如下。2.指定模塊別名>>>importsteakasS>>>S.make_steak(9,'salad')Makeasteakwelldonein9withtheother:-salad1導(dǎo)入函數(shù)目錄存儲并導(dǎo)入整個模塊2指定別名3【任務(wù)5-4】實現(xiàn)求方差函數(shù)存儲與導(dǎo)入4【任務(wù)5-4】實現(xiàn)求方差函數(shù)存儲與導(dǎo)入任務(wù)分析任務(wù)描述將自定義方差函數(shù)封裝并命名為var.py。(1)導(dǎo)入封裝好的函數(shù)模塊。(2)導(dǎo)入模塊中的特定函數(shù)var.var。(3)給函數(shù)指定別名fangcha。(5)給函數(shù)模塊指定別名V。(6)導(dǎo)入模塊中的所有函數(shù)。認識面向?qū)ο缶幊?體會面向?qū)ο髮嵗夸浢嫦驅(qū)ο缶幊碳跋嚓P(guān)內(nèi)容2面向?qū)ο蟮膬?yōu)點3何時使用面向?qū)ο缶幊?面向?qū)ο缶幊蹋∣bject-OrientedProgramming,OOP)即面向?qū)ο蟪绦蛟O(shè)計。在面向?qū)ο缶幊讨?,以類來?gòu)造現(xiàn)實世界中的事物和情景,再基于類創(chuàng)建對象來幫助用戶進一步認識、理解、刻畫這些事物和情景。基于類創(chuàng)建的對象都會自動帶有類的屬性和特點,還可以根據(jù)實際需要賦予每個對象特有的屬性,這個過程稱為類的實例化。從面向?qū)ο蟮脑O(shè)計(Object-OrientedDesign,OOD)的角度來看,類往往是由現(xiàn)實對象抽象而來的,抽象類可以看作基于類的進一步抽象。從實現(xiàn)角度來看,抽象類與普通類的不同之處在于:抽象類中可以包含抽象方法(沒有實現(xiàn)功能),此類不能被實例化,只能被繼承使用,且子類必須實現(xiàn)其中抽象方法。1.面向?qū)ο缶幊堂嫦驅(qū)ο蠓椒ǎ∣bject-OrientedMethod,OOM),是在軟件開發(fā)過程中以“對象”為中心,用面向?qū)ο蟮乃枷雭碇笇?dǎo)開發(fā)活動的系統(tǒng)方法。正如研究面向?qū)ο蠓椒ǖ膶<液蛯W(xué)者所說,面向?qū)ο蠓椒ㄍ?0世紀70年代的結(jié)構(gòu)化方法一樣,對計算機技術(shù)的應(yīng)用產(chǎn)生了巨大的影響,而且一直在強烈地影響和促進一系列高技術(shù)的發(fā)展和多學(xué)科的融合。2.面向?qū)ο蠓椒◤?0世紀80年代起,面向?qū)ο蟪绦蛟O(shè)計成了一種主導(dǎo)思想,但一直沒有專門的面向?qū)ο蟪绦蛟O(shè)計的語言。后因客觀需求的推動,人們進行了大量理論研究和實踐探索,不同類型的面向?qū)ο笳Z言(如Eiffel、C++、Java、Object-Pascal等)得以產(chǎn)生和發(fā)展,逐步解決了兼容性和維護性等問題。3.面向?qū)ο缶幊陶Z言1體會面向?qū)ο髮嵗夸浢嫦驅(qū)ο缶幊碳跋嚓P(guān)內(nèi)容2面向?qū)ο蟮膬?yōu)點3何時使用面向?qū)ο缶幊?面向過程是分析解決問題所需要的步驟,然后用函數(shù)一步步實現(xiàn)這些步驟。面向?qū)ο笫菍?gòu)成問題的事物分解成各個對象,創(chuàng)建對象是為了描述某個事物在解決問題過程中的行為。例如五子棋,面向過程的設(shè)計思路是分析解決問題的步驟,將每個步驟分別用函數(shù)來實現(xiàn),從而使問題得到解決,如下圖。而面向?qū)ο蟮脑O(shè)計則基于以下思路來解決問題:將五子棋分為3類對象,一是黑白雙方,雙方的行為是一模一樣的;二是棋盤系統(tǒng),負責(zé)繪制畫面;三是規(guī)則系統(tǒng),負責(zé)判斷諸如犯規(guī)、輸贏等。體會面向?qū)ο髮嵗梢钥吹剑嫦驅(qū)ο笫且怨δ軄韯澐謫栴}的,而不是循環(huán)步驟。同樣是繪制棋局,在面向過程的設(shè)計中,需要多個步驟來執(zhí)行該任務(wù),但這樣很可能會導(dǎo)致不同步驟繪制棋局的程序不同,因此程序設(shè)計人員會根據(jù)實際情況對繪制棋局的程序進行調(diào)整。而在面向?qū)ο蟮脑O(shè)計中,繪圖只可能在第2類對象中出現(xiàn),由此可以保證繪制棋局程序的統(tǒng)一。體會面向?qū)ο髮嵗?體會面向?qū)ο髮嵗夸浢嫦驅(qū)ο缶幊碳跋嚓P(guān)內(nèi)容2面向?qū)ο蟮膬?yōu)點3何時使用面向?qū)ο缶幊?面向?qū)ο笥幸韵?個優(yōu)點。(1)基于數(shù)據(jù)抽象的概念,面向?qū)ο罂梢栽诒3滞獠拷涌诓蛔兊那闆r下對內(nèi)部進行修改,從而減少甚至避免對外界的干擾。(2)面向?qū)ο笸ㄟ^繼承可以大幅減少冗余代碼,并可以方便地擴展現(xiàn)有代碼,提高編碼效率,降低出錯概率及軟件維護難度。(3)結(jié)合面向?qū)ο蠓治?、面向?qū)ο蟮脑O(shè)計,面向?qū)ο笤试S將問題中的對象直接映射到程序中,簡化了在軟件開發(fā)過程中中間環(huán)節(jié)的轉(zhuǎn)換過程。面向?qū)ο蟮膬?yōu)點1體會面向?qū)ο髮嵗夸浢嫦驅(qū)ο缶幊碳跋嚓P(guān)內(nèi)容2面向?qū)ο蟮膬?yōu)點3何時使用面向?qū)ο缶幊?在人工智能系統(tǒng)中,每個智能體或代理被看作一個類,具體的某個智能體或代理就是其中某個類的一個實例對象,所以每個智能體或代理的程序都具有一定的獨立性。對于小型程序和算法來說,面向?qū)ο蟮某绦蛞话銜让嫦蜻^程的程序慢,所以編寫程序時需要掌握面向?qū)ο蠛兔嫦蜻^程兩種思想,發(fā)揮每種思想的長處。何時使用面向?qū)ο缶幊填?綁定self參數(shù)目錄定義和使用類2類的專有方法3【任務(wù)6-1】創(chuàng)建Car類4類的定義和函數(shù)的定義相似,只是用class關(guān)鍵字替代了def關(guān)鍵字,同樣,在執(zhí)行class的整段代碼后,定義的類才會生效。進入類定義部分后,會創(chuàng)建一個新的局部作用域,在后面定義的類中,屬性和方法都是屬于局部作用域的局部變量。類的定義、類的使用定義類的格式如下。class類名:

屬性列表

方法列表當(dāng)使用class關(guān)鍵字創(chuàng)建類時,只要將所需的屬性列表和方法列表列出即可,代碼如下。類的使用>>>classCat:...'''一次模擬貓咪的簡單嘗試'''...#屬性...name='tesila'...age=3...#方法...defsleep(self):...'''模擬貓咪被命令睡覺'''...return'%d歲的%s正在沙發(fā)上睡懶覺。'%(self.age,)...defeat(self,food):...'''模擬貓咪被命令吃東西'''...self.food=food...return'%d歲的%s在吃%s。'%(self.age,,self.food)1綁定self參數(shù)目錄定義和使用類2類的專有方法3【任務(wù)6-1】創(chuàng)建Car類4Python的類的方法和普通的函數(shù)有一個很明顯的區(qū)別,就是類的方法必須有一個額外的參數(shù)self,并且在調(diào)用方法的時候不必為這個參數(shù)賦值。Python的類的方法的特別參數(shù)指代的是對象本身,而按照Python慣例,用self來表示。代碼如下。綁定self參數(shù)>>>classCat:...defsleep(self):...print(self)>>>new_cat=Cat()>>>new_cat.sleep()<__main__.Catobjectat0x000002794232A690>self參數(shù)代表當(dāng)前對象的地址,能避免非限定調(diào)用時找不到訪問對象或變量。當(dāng)調(diào)用sleep等函數(shù)時,會自動將該對象的地址作為第1個參數(shù)傳入;如果不傳入地址,程序?qū)⒉恢涝撛L問哪個對象。self這一名稱也不是必需的,在Python中,self不是關(guān)鍵字,可以將其定義成a、b或其他名字。利用my_address代替self,一樣不會出現(xiàn)錯誤,代碼如下。綁定self參數(shù)>>>classTest:...defprt(my_address):...print(my_address)...print(my_address.__class__)>>>t=Test()>>>t.prt()<__main__.Testobjectat0x000002794232AF90><class'__main__.Test'>1綁定self參數(shù)目錄定義和使用類2類的專有方法3【任務(wù)6-1】創(chuàng)建Car類4任何類都有類的專有方法,它們的特殊性從方法名就能看出,其通常使用雙下畫線“__”開頭和結(jié)尾。查看類或?qū)ο螅▽嵗┑膶傩院头椒ǎㄟ^點號操作來實現(xiàn),即object.attribute,也可以通過點號操作實現(xiàn)對屬性的修改和增加。查看類的屬性和方法的示例代碼如下。類的專有方法>>>classExample:...pass>>>example=Example()>>>print(dir(example))['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getstate__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__']定義類時只使用了pass語句,所以列出的結(jié)果都是以雙下畫線“__”開頭和結(jié)尾的。上面代碼的運行結(jié)果可知,使用dir函數(shù)可以查看類的屬性和方法。類的常用專有方法如下表。類的專有方法專有方法功

能專有方法功

能__init__構(gòu)造方法,生成對象時被調(diào)用__call__函數(shù)調(diào)用__del__析構(gòu)方法,釋放對象時被調(diào)用__add__加運算__repr__輸出類的實例化對象__sub__減運算__setitem__按照索引賦值__mul__乘運算__getitem__按照索引獲取值__div__除運算__len__獲得長度__mod__求余運算__cmp__比較運算__pow__冪運算__getitem__和__setitem__和普通的方法clear()、keys()、values()類似,只是重定向到字典,返回字典的值,通常不用直接調(diào)用,可以使用相應(yīng)的語法讓Python來調(diào)用__getitem__和__setitem__。__setitem__方法可以讓任何類像字典一樣保存鍵值對。__getitem__方法可以讓任何類表現(xiàn)得像一個序列。__repr__只有當(dāng)調(diào)用repr(instance)時才會被調(diào)用。repr函數(shù)是一個內(nèi)置函數(shù),它用于返回對象的可輸出形式字符串。__cmp__在比較類實例中被調(diào)用,通??梢酝ㄟ^使用“==”比較任意兩個Python對象,不只是類實例。類的專有方法__len__在調(diào)用len(instance)時被調(diào)用。len是Python的內(nèi)置函數(shù),可以返回一個對象的長度,對于字符串對象,返回的是字符個數(shù);對于字典對象,返回的是鍵值對的個數(shù);對于列表或序列,返回的是元素的個數(shù)。對于類和對象,定義__len__專有方法,可以自定義長度的計算方式,然后調(diào)用len(instance),Python則將調(diào)用定義的__len__專有方法。__del__在調(diào)用delinstance[key]時被調(diào)用,它會從字典中刪除單個元素。__call__方法讓一個類表現(xiàn)得像一個函數(shù),可以直接調(diào)用一個類實例。任何定義了__cmp__專有方法的類都可以用“==”進行比較。在類的應(yīng)用中,最常見的是先將類實例化,再通過實例來執(zhí)行類的專有方法。類的專有方法1綁定self參數(shù)目錄定義和使用類2類的專有方法3【任務(wù)6-1】創(chuàng)建Car類4【任務(wù)6-1】創(chuàng)建Car類任務(wù)分析任務(wù)描述創(chuàng)建一個Car類,代表一輛汽車,具有車輪數(shù)(4)和顏色(red)的屬性,以及兩個函數(shù):getCarInfo和run。通過實例化Car類并調(diào)用其方法,可以看到汽車的基本信息和行駛狀態(tài)。(1)使用class語句創(chuàng)建Car類,添加車輪數(shù)和顏色兩個屬性。(2)使用def關(guān)鍵字定義getCarInfo函數(shù),增加參數(shù)name,返回名字、車輪數(shù)和顏色3個屬性的字符串。(3)使用def關(guān)鍵字定義run函數(shù),返回語句“車行駛在學(xué)習(xí)的大道上?!?。(4)調(diào)用Car類賦值于new_car。(5)使用new_car調(diào)用getCarInfo函數(shù)和run函數(shù)。對象1刪除對象目錄創(chuàng)建對象2對象的屬性和方法3【任務(wù)6-2】創(chuàng)建Car對象4__init__是類的專有方法,每當(dāng)根據(jù)類創(chuàng)建新實例時,Python都會自動運行__init__。這是一個初始化手段,Python中的__init__方法用于初始化類的實例對象。創(chuàng)建對象的示例代碼如下。創(chuàng)建對象>>>classCat:...'''再次模擬貓咪的簡單嘗試'''...#構(gòu)造方法...def__init__(self,name,age):...#屬性...=name...self.age=age...defsleep(self):...'''模擬貓咪被命令睡覺'''...return'%d歲的%s正在沙發(fā)上睡懶覺。'%(self.age,)...defeat(self,food):...'''模擬貓咪被命令吃東西'''...self.food=food...return'%d歲的%s在吃%s'。%(self.age,,self.food)>>>cat1=Cat('Tom',3)1刪除對象目錄創(chuàng)建對象2對象的屬性和方法3【任務(wù)6-2】創(chuàng)建Car對象4刪除對象時,同樣會默認調(diào)用一個方法,這個方法為析構(gòu)方法。__del__也是類的專有方法,當(dāng)使用del語句刪除對象時,會調(diào)用__del__本身的析構(gòu)函數(shù)。當(dāng)對象在某個作用域中調(diào)用完畢,跳出其作用域時,析構(gòu)函數(shù)也會被調(diào)用一次,目的是釋放內(nèi)存空間。使用__del__方法刪除對象的具體示例代碼如下。刪除對象>>>classAnimal:...#構(gòu)造方法...def__init__(self):...print('---構(gòu)造方法被調(diào)用---')...#析構(gòu)方法...def__del__(self):...print('---析構(gòu)方法被調(diào)用---')>>>cat=Animal()---構(gòu)造方法被調(diào)用---刪除對象>>>print(cat)<__main__.Animalobjectat0x0000027942380450>>>>delcat---析構(gòu)方法被調(diào)用--->>>print(cat)NameError:name'cat'isnotdefined.1刪除對象目錄創(chuàng)建對象2對象的屬性和方法3【任務(wù)6-2】創(chuàng)建Car對象4學(xué)習(xí)了類的定義過程和方法后,可以嘗試創(chuàng)建具體的對象來進一步學(xué)習(xí)面向?qū)ο蟪绦蛟O(shè)計。創(chuàng)建對象的示例代碼如下。對象的屬性和方法classCat:def__init__(self,name,age):=nameself.age=agedefsleep(self):''''模擬貓咪被命令睡覺'''return'%d歲的%s正在沙發(fā)上睡懶覺。'%(self.age,)對象的屬性和方法defeat(self,food):'''模擬貓咪被命令吃東西'''self.food=foodreturn'%d歲的%s在吃%s。'%(self.age,,self.food)>>>#創(chuàng)建對象>>>cat1=Cat('Tom',3)>>>cat2=Cat('Jack',4)>>>#訪問對象的屬性>>>print('Cat1的名字為:',對象的屬性和方法Cat1的名字為:Tom>>>print('Cat2的名字為:',)Cat2的名字為:Jack>>>#訪問對象的方法>>>print(cat1.sleep())3歲的Tom正在沙發(fā)上睡懶覺。>>>print(cat2.eat('fish'))4歲的Jack在吃fish。對象屬性由類的每個實例對象擁有。因此每個對象有自己對這個域的一份備份,即它們不是共享的。在同一個類的不同實例對象中,即使對象的屬性有相同的名稱,也互不相關(guān)。對于類屬性和對象屬性,如果在類方法中引用某個屬性,那么該屬性必定是類屬性。要修改類屬性,如果在類外,那么可以通過類對象修改;如果在類里面,那么只能在類方法中進行修改。1.對象屬性對象方法和類的方法是一樣的。在定義類的方法時,程序沒有為類的方法分配內(nèi)存,只有在創(chuàng)建具體實例對象時,程序才會為對象的每個數(shù)據(jù)屬性和方法分配內(nèi)存。類的方法是由def關(guān)鍵字定義的,具體定義格式與普通函數(shù)的定義格式相似,只是類的方法的第一個參數(shù)需要是self參數(shù)。用普通函數(shù)可以實現(xiàn)對對象方法的引用,示例代碼如下。2.對象方法>>>cat1=Cat('Tom',3)>>>sleep=cat1.sleep>>>print(sleep())3歲的Tom正在沙發(fā)上睡懶覺。>>>cat2=Cat('Jack',4)>>>eat=cat2.eat>>>print(eat('fish'))4歲的Jack在吃fish。如果要獲取上述代碼中對象的數(shù)據(jù)屬性,并不需要通過sleep、eat等函數(shù),直接在程序外部調(diào)用數(shù)據(jù)屬性即可,示例代碼如下。3.私有化>>>print(cat1.age)3>>>print()Jack盡管直接調(diào)用的方法很方便,但是破壞了類的封裝性,這是因為對象的狀態(tài)對于類外部而言應(yīng)該是不可訪問的。為防止程序開發(fā)人員在無意中修改對象的狀態(tài),需要對類的數(shù)據(jù)屬性和方法進行私有化。Python提供了方法以達到私有化的目的。為了讓方法的數(shù)據(jù)屬性或方法變?yōu)樗接?,只需要在屬性或方法的名字前面加上雙下畫線即可,修改前文創(chuàng)建的Cat類代碼的示例如下。3.私有化>>>classCat:...def__init__(self,name,age):...self.__name=name...self.__age=age...defsleep(self):...return'%d歲的%s正在沙發(fā)上睡懶覺。'%(self.__age,self.__name)3.私有化...defeat(self,food):...self.__food=food...return'%d歲的%s在吃%s。'%(self.__age,self.__name,self.__food)...defgetAttribute(self):...returnself.__name,self.__age>>>#創(chuàng)建對象>>>cat1=Cat('Tom',3)>>>cat2=Cat('Jack',4)>>>print('Cat1的名字為:',)#從外部訪問對象的屬性,會發(fā)現(xiàn)訪問不了AttributeError:'Cat'objecthasnoattribute'name'3.私有化>>>print('Cat2的名字為:',)AttributeError:'Cat'objecthasnoattribute'name'>>>print(cat1.sleep())#只能通過設(shè)置好的接口函數(shù)來訪問對象3歲的Tom正在沙發(fā)上睡懶覺。>>>print(cat2.eat('fish'))4歲的Jack在吃fish。>>>print(cat1.getAttribute())('Tom',3)在程序外部直接訪問私有化屬性是不允許的,只能通過設(shè)置好的接口函數(shù)去調(diào)取對象的信息。通過雙下畫線實現(xiàn)的私有化其實是“偽私有化”,實際上還是可以從外部訪問這些私有化屬性,示例代碼如下。3.私有化>>>print(cat1._Cat__name)Tom>>>print(cat1._Cat__age)31刪除對象目錄創(chuàng)建對象2對象的屬性和方法3【任務(wù)6-2】創(chuàng)建Car對象4【任務(wù)6-2】創(chuàng)建Car對象任務(wù)分析任務(wù)描述在Python編程中,析構(gòu)函數(shù)是一個特殊的方法,用于在對象被銷毀時自動執(zhí)行清理操作。根據(jù)創(chuàng)建的Car類,為其定義一個析構(gòu)函數(shù)。(1)使用class語句創(chuàng)建Car類。(2)將Car類實例化,添加newWheelNuw和newColor兩個屬性。(3)使用def關(guān)鍵字定義run函數(shù),用print函數(shù)輸出“車在跑,目標(biāo):夏威夷?!?。(4)用def__del__定義析構(gòu)方法,用print函數(shù)輸出“---析構(gòu)方法被調(diào)用---”。(5)調(diào)用Car類,創(chuàng)建對象并命名為BMW。(6)訪問對象屬性,調(diào)用run函數(shù),并用print函數(shù)輸出。(7)用析構(gòu)方法刪除BMW,并查看對象是否被刪除。迭代對象1返回迭代器目錄生成迭代器2【任務(wù)6-3】迭代Car類3迭代是Python最強大的功能之一,是訪問集合元素的一種方式。之前介紹的Python容器對象都可以用for循環(huán)進行遍歷,代碼如下。生成迭代器>>>forelementin[1,2,3]:...print(element)123>>>forelementin(1,2,3):...print(element)123>>>forkeyin{'one':1,'two':2}:...print(key)onetwo>>>forcharin'123':...print(char)123>>>forlineinopen('../data/myfile.txt'):...print(line)123迭代器(iterator)有兩個基本的函數(shù):iter函數(shù)和next函數(shù)。如果for循環(huán)在容器對象上調(diào)用iter函數(shù),那么該函數(shù)會返回一個定義next函數(shù)的迭代對象,iter函數(shù)會在容器對象中逐一訪問元素。當(dāng)容器對象遍歷完畢,next函數(shù)找不到后續(xù)元素時,將會引發(fā)一個StopIteration異常,終止for循環(huán),代碼如下。生成迭代器>>>L=[1,2,3]>>>it=iter(L)>>>print(it)<list_iteratorat0xa9e0630>>>>print(next(it))1>>>print(next(it))2>>>print(next(it))3>>>print(next(it))StopIteration迭代器是一個可以記錄遍歷位置的對象,從第1個元素被訪問開始,直到所有元素被訪問完結(jié)束。迭代器只能往前,不能退后。要將迭代器加入類中,需要定義一個__iter__()方法,它返回一個有next函數(shù)的對象。如果類定義了next函數(shù),那么__iter__()方法可以只返回self參數(shù)。代碼示例如下。生成迭代器生成迭代器>>>classCat:...def__init__(self,name,age):...=name...self.age=age...=[,self.age]...self.index=-1...defgetName(self):...return...defgetAge(self):...returnself.age...def__iter__(self):...print('名字

年齡')...returnself...defnext(self):...ifself.index==len()-1:...raiseStopIteration...self.index+=1...return[self.index]>>>newcat=Cat('Coffe',3)#創(chuàng)建對象>>>print(newcat.getName())#訪問對象的屬性Coffe>>>iterator=iter(newcat.next,1)#調(diào)用迭代函數(shù)輸出對象的屬性>>>forinfoiniterator:...print(info)Coffe31返回迭代器目錄生成迭代器2【任務(wù)6-3】迭代Car類3生成器是一個返回迭代器的函數(shù),它可以通過常規(guī)的def關(guān)鍵字來定義,但是不用return語句返回,而是用yield語句一次返回一個結(jié)果。一般的函數(shù)在生成值后會退出,但生成器在生成值后會自動掛起,暫停執(zhí)行狀態(tài)并保存狀態(tài)信息。當(dāng)函數(shù)恢復(fù)時,這些狀態(tài)信息將再度生效,通過在每個結(jié)果之間掛起和繼續(xù)它們的狀態(tài)自動實現(xiàn)迭代器協(xié)議。通過生成斐波那契數(shù)列來對比有yield語句和沒有yield語句的情況,進一步了解生成器,代碼如下。1.yield語句1.yield語句>>>deffibonacci(n):#生成器——斐波那契數(shù)列...a,b,counter=0,1,0...whileTrue:...ifcounter>n:...return...yielda...a,b=b,a+b...print('%d,%d'%(a,b))...counter+=1>>>f=fibonacci(10)#f是一個迭代器,由生成器返回生成>>>whileTrue:...try:...print(next(f),end='')...except:...break01,111,212,323,535,858,13813,211321,342134,553455,895589,1441.yield語句>>>deffibonacci(n):...a,b,counter=0,1,0...whileTrue:...if(counter>n):...return...#yielda#不執(zhí)行yield語句...a,b=b,a+b...print('%d,%d'%(a,b))...counter+=1>>>f=fibonacci(10)1,11,22,33,55,88,1313,2121,3434,5555,8989,144列表解析的一般形式如下。2.生成器表達式[exprforiter_variniterableifcond_expr]1,2當(dāng)?shù)鷌terable里的所有內(nèi)容時,每一次迭代后,先將iterable里滿足cond_expr條件的內(nèi)容放到iter_var中,再在表達式expr中應(yīng)用iter_var的內(nèi)容,最后用表達式的計算值生成一個列表。例如,生成一個列表以保存50以內(nèi)的所有奇數(shù)。[iforiinrange(50)ifi%2]當(dāng)序列過長,而每次只需要獲取一個元素時,應(yīng)當(dāng)考慮使用生成器表達式生成器表達式是被圓括號括起來的,列表解析式是被方括號括起來的;生成器表達式返回的是一個生成器對象,而列表解析返回的是一個新列表。生成器表達式的一般形式如下。2.生成器表達式(exprforiter_variniterableifcond_expr)使用生成器表達式求出1~10內(nèi)3或5的倍數(shù),代碼如下。2.生成器表達式>>>g=(iforiinrange(1,10)ifi%3==0ori%5==0)>>>foriing:...print(i)35691返回迭代器目錄生成迭代器2【任務(wù)6-3】迭代Car類3【任務(wù)6-3】迭代Car類任務(wù)分析任務(wù)描述對Car類進行迭代,增加品牌(brand)和廢氣渦輪增壓(T)兩個屬性,并輸出所有屬性。(1)在原有Car類上增加品牌(brand)和廢氣渦輪增壓(T)兩個屬性。(2)使用方括號創(chuàng)建列表[brand,wheelnum,color,T],并賦值給變量(info)。(3)為迭代設(shè)置初始變量(index)。(4)使用def關(guān)鍵字分別定義getBrand、getNewheelnum、getNewcolor、getT函數(shù),用return語句返回對應(yīng)的屬性值。(5)使用def關(guān)鍵字定義__iter__函數(shù),用print函數(shù)輸出“品牌車輪數(shù)顏色廢氣渦輪增壓”,返回對象位置。(6)使用def關(guān)鍵字定義next函數(shù),用if語句進行判斷,返回對應(yīng)位置的屬性。(7)調(diào)用Car類,創(chuàng)建對象newcar,并輸出顏色屬性。(8)訪問對象屬性,調(diào)用iter函數(shù),并用print函數(shù)輸出結(jié)果。類的繼承、重寫、封裝、多態(tài)1其他方法目錄繼承父類屬性和方法2【任務(wù)6-4】創(chuàng)建Land_Rover子類3繼承(inheritance)是兩個類或多個類之間的父子關(guān)系,子類繼承了父類的所有公有數(shù)據(jù)屬性和方法,并且可以通過編寫子類的代碼擴充子類的功能。繼承實現(xiàn)了數(shù)據(jù)屬性和方法的重用,減少了代碼的冗余。在程序中,繼承描述的是事物之間的所屬關(guān)系。例如,貓和狗都屬于動物,在程序中便可以描述為貓和狗繼承自動物;同理,波斯貓和巴厘貓都繼承自貓,而沙皮狗和斑點狗都繼承自狗,如下圖。1.繼承特定狗種類繼承自狗類,狗類繼承自動物類,狗類編寫了描述所有種類的狗共有的行為和方法,而特定狗種類則增加了狗類特有的行為。繼承也有一定的弊端,例如,某種特定種類的狗不具有絕大部分狗的行為,當(dāng)程序員沒有厘清類間的關(guān)系時,可能會使子類具有不該有的方法。如果繼承鏈太長,那么任何一點小的變化都可能會引起一連串變化。因此,使用繼承時要注意控制繼承鏈的規(guī)模。1.繼承在Python中,繼承有以下特點。(1)在繼承中,基類初始化方法__init__()不會被自動調(diào)用。如果希望子類調(diào)用基類的__init__()方法,那么需要在子類的__init__()方法中顯式調(diào)用基類。(2)當(dāng)調(diào)用基類的方法時,需要加上基類的類名前綴,且?guī)蟬elf參數(shù)變量。注意,在類中調(diào)用該類定義的方法時是不需要self參數(shù)的。(3)Python總是先查找對應(yīng)類的方法,如果在子類中沒有對應(yīng)的方法,那么Python才會在繼承鏈的基類中按順序查找。(4)在Python的繼承機制中,子類不能訪問基類的私有成員。1.繼承1.繼承利用繼承機制修改Cat類的代碼,添加繼承方法,代碼如下。>>>classCat:...def__init__(self):...='貓'...self.age=4...=[,self.age]...self.index=-1...defrun(self):...returnf"{}--在跑"...defgetName(self):...return...defgetAge(self):...returnself.age...def__iter__(self):...print('名字

年齡')...returnself...defnext(self):...ifself.index==len()-1:...raiseStopIteration...self.index+=1...return[self.index]1.繼承>>>classBosi(Cat):...defsetName(self,newName):...=newName...defeat(self):...returnf"{}--在吃">>>bs=Bosi()#創(chuàng)建對象>>>print('bs的名字為:',)#繼承父類的屬性和方法bs的名字為:貓>>>print('bs的年齡為:',bs.age)bs的年齡為:4>>>print(bs.run())貓--在跑>>>bs.setName('波斯貓')#子類的屬性和方法>>>print(bs.eat())波斯貓--在吃>>>iterator=iter(bs.next,1)#迭代輸出父類的屬性>>>forinfoiniterator:...print(info)貓4上述代碼定義了Bosi類的父類Cat,將貓共有的屬性和方法都放到父類中,子類僅需要向父類傳輸數(shù)據(jù)屬性。這樣可以很輕松地定義其他基于Cat類的子類。在Bosi類的__init__()方法中顯式調(diào)用了Cat類的__init__()方法,并向父類傳輸數(shù)據(jù),注意這里需要加self參數(shù)。因為在繼承中子類不能繼承父類的私有屬性,所以不用擔(dān)心父類和子類會出現(xiàn)因繼承造成的重名情況。子類不能繼承父類的私有屬性的代碼如下。1.繼承1.繼承>>>classanimal:...def__init__(self,age):...self.__age=age...defprint2(self):...print(self.__age)>>>classdog(animal):...def__init__(self,age):...animal.__init__(self,age)...defprint2(self):...print(self.__age)>>>a_animal=animal(10)>>>a_animal.print2()10>>>a_dog=dog(10)>>>a_dog.print2()#程序報錯AttributeError:'dog'objecthasnoattribute'_

溫馨提示

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

評論

0/150

提交評論