




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Python進階學(xué)習(xí)筆記第1章課程介紹Python入門中我們學(xué)習(xí)了:如何安裝Python環(huán)境變量和數(shù)據(jù)類型:Python內(nèi)置的基本類型List列表和Tuple元組:順序的集合類型條件判斷和循環(huán):控制程序流程函數(shù):定義和調(diào)用函數(shù)切片:如何對list進行切片迭代:如何用for循環(huán)迭代集合類型列表生成式:如何快速生成列表Python進階課程我們講要學(xué)習(xí):函數(shù)式編程:不是函數(shù)編程哦,是函數(shù)式編程模塊:如何使用模塊面向?qū)ο缶幊蹋好嫦驅(qū)ο蟮母拍睢傩?、方法定制類:利用Python的特殊方法定制類第2章函數(shù)式編程函數(shù):function函數(shù)式:functional,一種編程范式函數(shù)式編程特點:把計算視為函數(shù)而非指令,貼近計算支持告誡函數(shù),代碼簡潔Python不是純函數(shù)式編程:允許有變量支持高階函數(shù):函數(shù)也可以作為變量傳入支持閉包:有了閉包就能返回函數(shù)有限度的支持匿名函數(shù)高階函數(shù)變量可以指向函數(shù),函數(shù)名其實就是指向函數(shù)的變量,而高階函數(shù)其實就是可以接收函數(shù)做參數(shù)的函數(shù)。Len([1,2,3])=3Demo:接收abs函數(shù)函數(shù)。defadd(x,y,f)returnf(x)+f(y)把函數(shù)作為參數(shù)傳入另一個函數(shù)創(chuàng)建實例屬性Personxiaoming、xiaohongxiaomingxiaohong要依靠他們各自的名字、性別、生日等屬性。Pythonxiaomingnamegenderbirth屬性:xiaoming=Person()='XiaoMing'xiaoming.gender='Male'xiaoming.birth='1990-1-1'給xiaohong加上的屬性不一定要和xiaoming相同:xiaohong=Person()='XiaoHong'xiaohong.school='No.1HighSchool'xiaohong.grade=2實例的屬性可以像普通變量一樣進行操作:xiaohong.grade=xiaohong.grade+1任務(wù)請創(chuàng)建包含兩個Person類的實例的list,并給兩個實例的name賦值,然后按照name進行排序。sorted()是高階函數(shù),接受一個比較函數(shù)。參考代碼:classPerson(object):passp1=Person()='Bart'p2=Person()='Adam'p3=Person()=L1=[p1,p2,p3]L2=sorted(L1,lambdap1,p2:cmp(,))printL2[0].nameprintL2[1].nameprintL2[2].name初始化實例屬性son類ngenderbirthPersonPersoninit(),init()classPerson(object):definit(self,name,gender,birth):=nameself.gender=genderself.birth=birthinit()法,后續(xù)參數(shù)則可以自由指定,和定義函數(shù)沒有任何區(qū)別。相應(yīng)地,創(chuàng)建實例時,就必須要提供除self以外的參數(shù):xiaoming=Person('XiaoMing','Male','1991-1-1')xiaohong=Person('XiaoHong','Female','1992-2-2')有了init()Personnamegenderbirth這3個屬性,并且,被賦予不同的屬性值,訪問屬性使用.操作符:print#輸出'XiaoMing'printxiaohong.birth#輸出'1992-2-2'要特別注意的是,初學(xué)者定義init()self參數(shù):>>>classPerson(object):... definit(name,birth):... pass...>>>xiaoming=Person('XiaoMing','Male','1990-1-1')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:init()takesexactly3arguments(4given)這會導(dǎo)致創(chuàng)建失敗或運行不正常,因為第一個參數(shù)name被Python解釋器傳入了實例的引用,從而導(dǎo)致整個方法的調(diào)用參數(shù)位置全部沒有對上。任務(wù)Person類的initnamegenderbirth要定義關(guān)鍵字參數(shù),使用**kw;除了可以直接使用='xxx'設(shè)置一個屬性外,還可以通過setattr(self,'name','xxx')設(shè)置屬性。參考代碼:classPerson(object):definit(self,name,gender,birth,**kw):=nameself.gender=genderself.birth=birthfork,vinkw.iteritems():setattr(self,k,v)xiaoming=Person('XiaoMing','Male','1990-1-1',job='Student')printprintxiaoming.job訪問限制Python對屬性權(quán)限的控制是通過屬性名來實現(xiàn)的,如果一個屬性由雙下劃線開頭(),該屬性就無法被外部訪問??蠢樱篶lassPerson(object):definit(self,name):=nameself._title='Mr'job='Student'p=Person('Bob')print#=>Bobprintp._title#=>Mrprintp.job#=>Error(mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'Person'objecthasnoattribute'job'可見,只有以雙下劃線開頭的"job"不能直接被外部訪問。但是,如果一個屬性以"xxx"的形式定義,那它又可以被外部訪問了,以"xxx"定義的屬性在Python的類中被稱為特殊屬性,有很多預(yù)定義的特殊屬性可以使用,通常我們不要把普通屬性用"xxx"定義。以單下劃線開頭的屬性"_xxx"雖然也可以被外部訪問,但是,按照習(xí)慣,他們不應(yīng)該被外部訪問。任務(wù)Person類的initnamescorescore綁定到score屬性上,看看外部是否能訪問到。以雙下劃線開頭的屬性無法被外部訪問,"xxx"除外。參考代碼:classPerson(object):definit(self,name,score):=namescore=scorep=Person('Bob',59)printprintp.score輸出結(jié)果:BobTraceback(mostrecentcalllast):File"./6172/58Wr/index.py",line9,inprintp.scoreAttributeError:'Person'objecthasnoattribute'score'創(chuàng)建類屬性類是模板,而實例則是根據(jù)類創(chuàng)建的對象。綁定在一個實例上的屬性不會影響其他實例,但是,類本身也是一個對象,如果性有且只有一份。定義類屬性可以直接在class中定義:classPerson(object):address='Earth'definit(self,name):=name接訪問:printPerson.address#=>Earth屬性:p1=Person('Bob')p2=Person('Alice')printp1.address#=>Earthprintp2.address#=>Earth由于Python是動態(tài)語言,類屬性也是可以動態(tài)添加和修改的:Person.address='China'printp1.address#=>'China'print#=>'China'Personaddress類屬性都改變了。任務(wù)PersonPerson?不會了怎么辦由于創(chuàng)建實例必定會調(diào)用init()方法,所以在這里修改類屬性count很合適。參考代碼:classPerson(object):count=0definitname):Person.count=Person.count+1=namep1=Person('Bob')printPerson.count#=>1p2=Person('Alice')printPerson.count#=>2p3=Person('Tim')printPerson.count#=>3#輸出結(jié)果:123類屬性和實例屬性名字沖突怎么辦量上修改類屬性會發(fā)生什么問題呢?classPerson(object):address='Earth'definit(self,name):=namep1=Person('Bob')p2=Person('Alice')print'Person.address='+Person.addressp1.address='China'print'p1.address='+p1.addressprint'Person.address='+Person.addressprint'p2.address='+p2.address結(jié)果如下:Person.address=Earthp1.address=ChinaPerson.address=Earthp2.address=Earthp1.address'China'address'China',但是,Person.addressp2.address仍然是'Earch',怎么回事?原因是p1.address='China'并沒有改變Person的address,而是給p1這個實例綁定了實例屬性ds1而它所屬的類Person也有一個類屬性address,所以:訪問p1.address時,優(yōu)先查找實例屬性,返回'China'。
'hina'訪問p2.address時,p2沒有實例屬性address,但是有類屬性address,因此返回'Earth'。訪問。當(dāng)我們把p1的address實例屬性刪除后,訪問p1.address就又返回類屬性的值'Earth'了:delp1.addressprintp1.address#=>Earth綁定了一個實例屬性。任務(wù)Personcount改為count改為私有countcount參考代碼:classPerson(object):count=0definit(self,name):Person.count=Person.count+1=nameprintPerson.countp1=Person('Bob')p2=Person('Alice')printPerson.count#輸出結(jié)果:不可以定義實例方法一個實例的私有屬性就是以什么用?實例的屬性外,還可以定義實例的方法。實例的方法就是在類中定義的函數(shù),它的第一個參數(shù)永遠是self,指向調(diào)用該方法的實例本身,其他參數(shù)和一個普通函數(shù)是完全一樣的:classPerson(object):definitname):name=defget_name(self):returnnameget_name(self)self。init,name)其實也可看做是一個特殊的實例方法。調(diào)用實例方法必須在實例上調(diào)用:p1=Person('Bob')printp1.get_name() self不需要顯式傳入#=>Bob任務(wù)Person類增加一個私有屬性score,表示分數(shù),再增加一個實例方get_grade(),能根據(jù)scoreA-優(yōu)秀B-及格C-不及格三檔。?不會了怎么辦get_grade()self參考代碼:classPerson(object):definitname,score):name=nameself.score=scoredefget_grade(self):ifscore>=80:return'A'ifscore>=60:return'B'return'C'p1=Person('Bob',90)p2=Person('Alice',65)p3=Person('Tim',48)printp1.get_grade()printp2.get_grade()printp3.get_grade()#輸出結(jié)果:ABC方法也是屬性我們在class中定義的實例方法其實也是屬性,它實際上是一個函數(shù)對象:classPerson(object):definit(self,name,score):=nameself.score=scoredefget_grade(self):return'A'p1=Person('Bob',90)printp1.get_grade#=><boundmethodPerson.get_gradeof<main.Personobjectat0x109e58510>>printp1.get_grade()#=>A也就是說,p1.get_grade返回的是一個函數(shù)對象,但這個函數(shù)是一個綁定到實例的函數(shù),p1.get_grade()才是方法調(diào)用。因為方法也是一個屬性,所以,它也可以動態(tài)地添加到實例上,只是需要用types.MethodType把一個函數(shù)變?yōu)橐粋€方法:importtypesdeffn_get_grade(self):ifself.score>=80:return'A'if>=60:return'B'return'C'classPerson(object):definit(self,name,score):=nameself.score=scorep1=Person('Bob',90)p1.get_grade=types.MethodType(fn_get_grade,p1,Person)printp1.get_grade()#=>Ap2=Person('Alice',65)printp2.get_grade()#ERROR:AttributeError:'Person'objecthasnoattribute'get_grade'#因為p2實例并沒有綁定get_grade給一個實例動態(tài)添加方法并不常見,直接在class中定義要更直觀。任務(wù)由于屬性可以是普通的值對象,如str,int等,也可以是方法,還可以是函數(shù),p1.get_gradeclassPerson(object):definit(self,name,score):=nameself.score=scoreself.get_grade=lambda:'A'p1=Person('Bob',90)printp1.get_gradeprintp1.get_grade()lambdaself.get_gradeselfself。#輸出結(jié)果:at0x12f7e7d0>A定義類方法和屬性類似,方法也分實例方法和類方法。classselfclass中定義類方法,需要這么寫:classPerson(object):count=0@classmethoddefhow_many(cls):returncls.countdefinit(self,name):=namePerson.count=Person.count+1printPerson.how_many()p1=Person('Bob')printPerson.how_many()通過標(biāo)記一個@classmethodPerson類上,而非類的實例。類clscls.count實Person.count。獲得類的引用。任務(wù)count改為私有屬性count,則外部無法讀取score,但可以通過一個類方法獲取,請編寫類方法獲得count值。?不會了怎么辦注意類方法需要添加@classmethod參考代碼:classPerson(object):count=0@classmethoddefhow_many(cls):returncls.countdefinit(self,name):=namePerson.count=Person.count+1printPerson.how_many()p1=Person('Bob')printPerson.how_many()#輸出結(jié)果:01第3章類的繼承什么是類的繼承:genderschoolscore,是否需要重新編寫呢?但是我們知道已有的Person類:classPerson(object):definit(self,name,gender):=nameself.gender=gender里面存在已有屬性:name,gender我們可以這樣:classStudent(Person):definit(self,name,gender,school,score):super(Student,self).init(name,gender)self.school=school=score缺少的功能只需要編寫即可繼承的好處:復(fù)用已有代碼,自動擁有現(xiàn)有類的所有功能,只需要編寫缺少的功能父類與子類派生類,繼承類繼承的特點:(1).子類和父類是is關(guān)系:classStudent(Person):passp=Person()s=Student()“p”是一個Person類,而不是一個Student類;s是一個Student類,也是一個Person類(2).錯誤的繼承:Student類和Book類是has關(guān)系classStudent(Person):definit(self,bookName):=Book(bookName)(3).Python的繼承特點:總是從某個類繼承,如果沒有合適的類,就從object類繼承:classMyClass(object):passsuper().init(self,args):super(SubClass,self).init(args)pass如果沒有使用,那么父類的屬性很有可能就沒有初始化。繼承一個類如果已經(jīng)定義了Person類,需要定義新的Student和Teacher類時,可以直接從Person類繼承:classPerson(object):definit(self,name,gender):=nameself.gender=genderStudentscore:classStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=score一定要用super(Student,self).init(name,gender)去初始化父類,否則,繼承自Person的Student將沒有name和gender。super(Student,self)Personinit()selfsuper()init()(也不能寫任務(wù)請參考Student類,編寫一個Teacher類,也繼承自Person。super()的init參考代碼:classPerson(object):definitname,gender):=nameself.gender=genderclassTeacher(Person):definit(self,name,gender,course):super(Teacher,self).init(name,gender)self.course=courset=Teacher('Alice','Female','English')printprintt.course#輸出結(jié)果:AliceEnglish判斷類型函數(shù)isinstance()可以判斷一個變量的類型,既可以用在Python內(nèi)置的數(shù)據(jù)類型如str、list、dict,也可以用在我們自定義的類,它們本質(zhì)上都是數(shù)據(jù)類型。假設(shè)有如下的Person、Student和Teacher的定義及繼承關(guān)系如下:classPerson(object):definit(self,name,gender):=nameself.gender=genderclassStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoreclassTeacher(Person):definit(self,name,gender,course):super(Teacher,self).init(name,gender)self.course=coursep=Person('Tim','Male')s=Student('Bob','Male',88)t=Teacher('Alice','Female','English')當(dāng)我們拿到變量p、s、t時,可以使用isinstance判斷類型:>>>isinstance(p,Person)p是Person類型>>>isinstance(p,Student)False pStudent>>>isinstance(p,Teacher)False #p類型屬性和方法。我們再考察s:>>>isinstance(s,Person)sPerson類型>>>isinstance(s,Student)sStudent>>>isinstance(s,Teacher)False #s類型sStudentPerson類型,tuetnens看成Person的實例也是可以的。類型。任務(wù)t類isinstance()判斷來驗證您的答案。注意t是Teacher的實例,繼承鏈?zhǔn)牵簅bject<-Person<-Teacher參考代碼:classPerson(object):definit(self,name,gender):=nameself.gender=genderclassStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoreclassTeacher(Person):definit(self,name,gender,course):super(Teacher,self).init(name,gender)self.course=courset=Teacher('Alice','Female','English')printisinstance(t,Person)printisinstance(t,Student)printisinstance(t,printisinstance(t,object)#輸出結(jié)果:TrueTrueFalseTrue多態(tài)類具有繼承關(guān)系,并且子類類型可以向上轉(zhuǎn)型看做父類類型,如果我們PersonStudentwhoAmI()classPerson(object):definit(self,name,gender):=nameself.gender=genderdefwhoAmI(self):return'IamaPerson,mynameis%s'%classStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoredefwhoAmI(self):return'IamaStudent,mynameis%s'%classTeacher(Person):definit(self,name,gender,course):super(Teacher,self).init(name,gender)self.course=coursedefwhoAmI(self):return'IamaTeacher,mynameis%s'%在一個函數(shù)中,如果我們接收一個變量x,則無論該x是Person、Student還是Teacher,都可以正確打印出結(jié)果:defwho_am_i(x):printx.whoAmI()p=Person('Tim','Male')s=Student('Bob','Male',88)t=Teacher('Alice','Female','English')who_am_i(p)who_am_i(s)who_am_i(t)運行結(jié)果:IamaPerson,mynameisTimIamaStudent,nameisBobIamanameisAlicexsStudentwhoAmI()PersonwhoAmI方法,s.whoAmI()由于Python是動態(tài)語言,所以,傳遞給函數(shù)who_am_i(x)的參數(shù)x不一定是Person或Person的子類型。任何數(shù)據(jù)類型的實例都可以,只要它有一個whoAmI()的方法即可:classBook(object):defwhoAmI(self):return'Iamabook'(Ja不檢查類型,只要方法存在,參數(shù)正確,就可以調(diào)用。任務(wù)Pythonopen()FileFile對象有一read()方法可以讀取文件內(nèi)容:例如,從文件讀取內(nèi)容并解析為JSON結(jié)果:importjsonf=open('/path/to/file.json','r')printjson.load(f)Pythonjson.load()Fileread()File-likeObjectjson.load()。請嘗試編寫一個File-likeObject,把一個字符串r'["Tim","Bob","Alice"]'包裝成File-likeObject并由json.load()解析。?不會了怎么辦Studentsread()File-likeObject。參考代碼:importjsonclassStudents(object):defread(self):returnr'["Tim","Bob","Alice"]'s=Students()printjson.load(s)#輸出結(jié)果:[u'Tim',u'Bob',u'Alice']多重繼承除了從一個父類繼承外,Python允許從多個父類繼承,稱為多重繼承。多重繼承的繼承鏈就不是一棵樹了,它像這樣:classA(object):definit(self,a):print'initA...'self.a=aclassB(A):definit(self,a):super(B,self).init(a)print'initB...'classC(A):definit(self,a):super(C,self).init(a)print'initC...'classD(B,C):definit(self,a):super(D,self).init(a)print'initD...'看下圖:BDABCsupr(調(diào)用iitAnit()只調(diào)用一次:>>>d=D('d')initA...initC...initB...initD...多重繼承的目的是從兩種繼承樹中分別選擇并繼承出子類,以便組合功能使用。舉個例子,Python的網(wǎng)絡(luò)服務(wù)器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服務(wù)器運行模式有多進程ForkingMixin和多線程ThreadingMixin兩種。要創(chuàng)建多進程模式的TCPServer:classMyTCPServer(TCPServer,ForkingMixin)pass要創(chuàng)建多線程模式的UDPServer:classMyUDPServer(UDPServer,ThreadingMixin):pass如果沒有多重繼承,要實現(xiàn)上述所有可能的組合需要4x2=8個子類。任務(wù)+-Person+-Student+-是一類繼承樹;+-SkillMixin+-BasketballMixin+-FootballMixin是一類繼承樹。通過多重繼承,請定義“會打籃球的學(xué)生”和“會踢足球的老師”。多重繼承需要從兩個或更多的類派生。參考代碼:classPerson(object):passclassStudent(Person):passclasspassclassSkillMixin(object):passclassBasketballMixin(SkillMixin):defskill(self):return'basketball'classFootballMixin(SkillMixin):defskill(self):return'football'classBStudent(Student,BasketballMixin):passclassFootballMixin):passs=prints.skill()t=printt.skill()#輸出結(jié)果:basketballfootball獲取對象信息isinstance(例如,已有定義:classPerson(object):definit(self,name,gender):=nameself.gender=genderclassStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoredefwhoAmI(self):return'IamaStudent,mynameis%s'%首先可以用type()函數(shù)獲取變量的類型,它返回一個Type對象:>>>type(123)<type'int'>>>>s=Student('Bob','Male',88)>>>type(s)<class'main.Student'>其次,可以用dir()函數(shù)獲取變量的所有屬性:>>>dir(123) #...['abs','add','and','class','cmp',...]>>>dir(s)['class',delattr','dict','doc','format','getattribute','hash','init',module','new','reduce','reduce_ex','repr','setattr','sizeof','str',subclasshook','weakref','gender','name','score','whoAmI']`class`s的一個屬性。如何去掉`xxx`這類的特殊屬性,只保留我們自己定義的屬性?回顧一下filter()函數(shù)的用法。dir()返回的屬性是字符串列表,如果已知一個屬性名稱,要獲取或者設(shè)置對象的屬性,就需要用getattr()和setattr()函數(shù)了:getattr(s'name') #name屬性'Bob'>>>setattr(s,'name','Adam')#設(shè)置新的name屬性>>>'Adam'getattr(s'age') #age屬性,但是屬性不存在,報錯:(mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'Student'objecthasnoattribute'age'>>>getattr(s'age',20) #age20任務(wù)對于Person類的定義:classPerson(object):definit(self,name,gender):=nameself.gender=gendername和genderPerson的init()定義,完成該功能。?不會了怎么辦傳入**kw即可傳入任意數(shù)量的參數(shù),并通過setattr()綁定屬性。參考代碼:classPerson(object):definit(self,name,gender,**kw):=nameself.gender=genderfork,vinkw.iteritems():setattr(self,k,v)p=Person('Bob','Male',age=18,course='Python')printprintp.genderprintp.ageprintp.course#輸出結(jié)果:BobMale18Python第6章定制類什么是特殊方法1.例子:比較print的結(jié)果:>>>printlst[1,2,3]>>>printp<main.Personobjectat0x10da9e850>問題:Python是如何把任意變量變成str?因為任何數(shù)據(jù)類型的實例都有一個特殊方法,即:str()>>>printlst.str()[1,2,3]>>>printp.str()<main.Personobjectat0x10da9e850>2.Python的特殊方法:(1).print的str方法(2).len的len方法(3).cmp的cmp方法……特點:(1).特殊方法定義在class中(2).不需要直接調(diào)用(3).Python的某些函數(shù)或操作符調(diào)用對應(yīng)的特殊方法3.正確的視線特殊方法(1).只需要編寫用到的特殊方法(2).有關(guān)聯(lián)性的特殊方法都必須實現(xiàn)getattr;; delattr 和 strstr():classPerson(object):definit(self,name,gender):=nameself.gender=genderdefstr(self):return'(Person:%s,%s)'%(,self.gender)現(xiàn)在,在交互式命令行下用print試試:>>>p=Person('Bob','male')>>>printp(Person:Bob,但是,如果直接敲變量p:>>>p<main.Personobjectat0x10c941890>似乎str()因為Python定義了str()和repr()兩種方法,str()用于顯示給用戶,而repr()用于顯示給開發(fā)人員。有一個偷懶的定義repr的方法:classPerson(object):definit(self,name,gender):=nameself.gender=genderdefstr(self):return'(Person:%s,%s)'%(,self.gender)repr =str 任務(wù)Student類定義str和repr<Student:name,score>:classStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoreStudents類加上str()和repr()classPerson(object):definit(self,name,gender):=nameself.gender=genderclassStudent(Person):definit(self,name,gender,score):super(Student,self).init(name,gender)self.score=scoredefstr(self):return'(Student:%s,%s,%s)'%(,self.gender,self.score)repr =str s=Student('Bob','male',88)prints#輸出結(jié)果:(Student:Bob,male,88) int、str等內(nèi)置數(shù)據(jù)類型排序時,Pythonsorted()按照默認的比較函cmpStudentcmp():classStudent(object):definit(self,name,score):=nameself.score=scoredefstr(self):return'(%s:%s)'%(,self.score)repr =str defcmp(self,s):if<:return-1elif>:return1else:return0上述Student類實現(xiàn)了cmp()方法,cmp用實例自身self和傳入的實sselfs1,如果兩者相當(dāng),返回0。Student類實現(xiàn)了按name進行排序:>>>L=[Student('Tim',99),Student('Bob',88),Student('Alice',77)]>>>printsorted(L)[(Alice:77),(Bob:88),(Tim:99)]注意:如果list不僅包含Student類,則cmp 可能會報錯:L=[Student('Tim',99),Student('Bob',88),100,'Hello']printsorted(L)請思考如何解決。任務(wù)請修改Student的cmp 方法讓它按照數(shù)從高到底排序分數(shù)相同的按名字排序。scorescorename。參考代碼:classStudent(object):definit(self,name,score):=nameself.score=scoredefstr(self):return'(%s:%s)'%(,self.score)repr =str defcmp(self,s):ifself.score==s.score:returncmp(,)return-cmp(self.score,s.score)L=[Student('Tim',99),Student('Bob',88),Student('Alice',99)]printsorted(L)#輸出結(jié)果:[(Alice:99),(Tim:99),(Bob:88)] len 如果一個類表現(xiàn)得像一個list,要獲取有多少個元素,就得用len()函數(shù)。len()lenStudents類,把名字傳進去:classStudents(object):definit(self,*args):s=argsdeflen(self):returnlen(s)只要正確實現(xiàn)了len()len()Students“長度”:>>>ss=Students('Bob','Alice','Tim')>>>printlen(ss)3任務(wù)斐波那契數(shù)列是由0,1,1,2,3,5,8...構(gòu)成。請編寫一個Fib類,F(xiàn)ib(10)表示數(shù)列的前10個元素,printFib(10)可以打印出數(shù)列的前10個元素,len(Fib(10))可以正確返回數(shù)列的個數(shù)10。numN參考代碼:classFib(object):definitnum):a,b,L=0,1,[]forninrange(num):L.append(a)a,b=b,a+bself.numbers=Ldefstr(self):returnstr(self.numbers)repr =str deflen(self):returnlen(self.numbers)f=Fib(10)printfprintlen(f)#輸出結(jié)果:[0,1,1,2,3,5,8,13,21,34]10數(shù)學(xué)運算PythonintfloatintfloatRational類classRational(object):definitp,q):=p=qp、q都是整數(shù),表示有理數(shù)p/q。Rational進行+運算,需要正確實現(xiàn)add:classRational(object):definitp,q):=p=qdefadd(self,r):returnRational(self.p*+**defstr(self):return'%s/%s'%(self.p,self.q)repr =str 現(xiàn)在可以試試有理數(shù)加法:>>>r1=Rational(1,3)>>>r2=Rational(1,2)>>>printr1+r25/6任務(wù)Rational類雖然可以做加法,但無法做減法、乘方和除法,請繼續(xù)完善Rational類,實現(xiàn)四則運算。提示:減法運算:sub 乘法運算:mul 除法運算:div 如果運算結(jié)果是6/8,在顯示的時候需要歸約到最簡形式3/4。參考代碼:defgcd(a,b):ifb==0:returnareturngcd(b,a%b)classRational(object):definitp,q):=p=qdefaddr):returnRational(self.p*+**defsubr):returnRational(self.p*-**defmulr):returnRational(self.p**defdivr):returnRational(self.p**defstr(self):g=gcd(self.p,self.q)return'%s/%s'%(self.p/g,self.q/g)repr =str r1=Rational(1,r2=Rational(1,printr1+r2printr1-r2printr1*printr1/r2#輸出結(jié)果:3/41/41/82/1類型轉(zhuǎn)換Rationalintfloat怎么辦?考察整數(shù)和浮點數(shù)的轉(zhuǎn)換:>>>int(12.34)12>>>float(12)12.0如果要把Rational轉(zhuǎn)為int,應(yīng)該使用:r=Rational(12,5)n=int(r)int()int():classRational(object):definit(self,p,q):self.p=p=qdefint(self):returnself.p//self.q結(jié)果如下:>>>printint(Rational(7,2))3>>>printint(Rational(1,3))0float()float()。任務(wù)請繼續(xù)完善Rational,使之可以轉(zhuǎn)型為float。將self.p轉(zhuǎn)型為float類型,再作除法就可以得到float:float(self.p)/self.q參考代碼:classRational(object):definitp,q):=p=qdefint(self):returnint(self.p)//self.qdeffloat(self):returnfloat(self.p)/self.qprintfloat(Rational(7,2))printfloat(Rational(1,3))#輸出結(jié)果:3.50.333333333333@property考察Student類:classStudent(object):definit(self,name,score):=nameself.score=score當(dāng)我們想要修改一個Student的scroe屬性時,可以這么寫:s=Student('Bob',59)s.score=60但是也可以這么寫:s.score=1000如果利用兩個方法:classStudent(object):definit(self,name,score):=nameself.score=scoredefget_score(self):returnscoredefset_score(self,score):ifscore<0orscore>100:raiseValueError('invalidscore')self.score=score這樣一來,s.set_score(1000)就會報錯。這種使用get/set方法來封裝對一個屬性的訪問在許多面向?qū)ο缶幊痰恼Z言中都很常見。但是寫s.get_score()和s.set_score()沒有直寫s.score來得直接。有沒有兩全其美的方法? 有。因為Python支持高階函數(shù),在函數(shù)式編程中我們介紹了裝飾器函數(shù),可以用裝飾器函數(shù)把get/set方法“裝飾”成屬性調(diào)用:classStudent(object):definit(self,name,score):=nameself.score=score@propertydefscore(self):returnself.score@score.setterdefscore(self,score):ifscore<0orscore>100:raiseValueError('invalidscore')self.score=score注意score(self)get方法,用@propertyscore(self,score)set\h方法,用@sc\hore.setter裝飾,@score.setter是前一個@property裝飾后的副產(chǎn)品?,F(xiàn)在,就可以像使用屬性一樣設(shè)置score了:>>>s=Student('Bob',59)>>>s.score=60>>>prints.score60>>>s.score=1000Traceback(mostrecentcalllast):...ValueError:invalidscorescoreset方法任務(wù)如果沒有定義set方法,就不能對“屬性”賦值,這時,就可以創(chuàng)建一個只讀“屬性”。Studtdesce計算A(0、、(60用@property修飾grade的get方法即可實現(xiàn)只讀屬性。參考代碼:classStudent(object):definit(self,name,score):=nameself.sco
溫馨提示
- 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. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 三年級教師線上教學(xué)總結(jié)
- 廠區(qū)電子合同范本
- 勞務(wù)磚體合同范本
- 印刷廣告標(biāo)牌合同范本
- 企業(yè)員工股合同范本
- 《韓愈短文》教案
- 合買別墅合同范本
- 《這片土地是神圣的》說課稿
- 《觀滄?!烽喿x答案及鑒賞
- 任務(wù)目標(biāo)認購合同范例
- 常見急危重癥的快速識別要點與處理技巧課件
- 耳鼻咽喉科中級職稱(主治醫(yī)師)考試重點
- 高危妊娠及五色管理課件
- 《 大學(xué)生軍事理論教程》全套教學(xué)課件
- 三年級數(shù)學(xué)下冊一兩位數(shù)乘兩位數(shù)的乘法2問題解決作業(yè)課件西師大版
- 家校溝通經(jīng)驗分享-溝通有方法教育有溫度
- 2024年福建省廈門市翔安區(qū)殘疾人聯(lián)合會招聘殘疾人工作聯(lián)絡(luò)員29人歷年重點基礎(chǔ)提升難、易點模擬試題(共500題)附帶答案詳解
- 幼兒園家長會疾病預(yù)防
- 《儲糧害蟲防治技術(shù)》課件-第六章 儲糧保護劑及其應(yīng)用
- 排水管道施工組織設(shè)計排水管道施工組織設(shè)計排水施工排水管道施工施工設(shè)計
- 2024未來會議:AI與協(xié)作前沿趨勢白皮書
評論
0/150
提交評論