Python中面向对象的编程
Python面向?qū)ο蟮木幊?/span>
1概述
(1)面向?qū)ο缶幊?/span>
??面向?qū)ο蟮木幊淌抢谩邦悺焙汀皩?duì)象”來創(chuàng)建各種模型來實(shí)現(xiàn)對(duì)真實(shí)世界的描述,使用面向?qū)ο缶幊痰脑蛞环矫媸且驗(yàn)樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡(jiǎn)單,并且可以大大提高程序開發(fā)效率,另外,基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯,從而使團(tuán)隊(duì)開發(fā)變得更從容。
(2)面向?qū)ο蟮奶卣?/span>
? ?1)類(Class):一個(gè)類即是對(duì)一類擁有相同屬性的對(duì)象的抽象、藍(lán)圖、原型。在類中定義了這些對(duì)象的都具備的屬性(variables(data))、共同的方法
? ?2)對(duì)象(Object)?:一個(gè)對(duì)象即是一個(gè)類的實(shí)例化后實(shí)例,一個(gè)類必須經(jīng)過實(shí)例化后方可在程序中調(diào)用,一個(gè)類可以實(shí)例化多個(gè)對(duì)象,每個(gè)對(duì)象亦可以有不同的屬性,就像人類是指所有人,每個(gè)人是指具體的對(duì)象,人與人之前有共性,亦有不同
? ?3)封裝(Encapsulation):在類中對(duì)數(shù)據(jù)的賦值、內(nèi)部調(diào)用對(duì)外部用戶是透明的,這使類變成了一個(gè)膠囊或容器,里面包含著類的數(shù)據(jù)和方法
? ?4)繼承(Inheritance):一個(gè)類可以派生出子類,在這個(gè)父類里定義的屬性、方法自動(dòng)被子類繼承
? ?5)多態(tài)(Polymorphism):多態(tài)是面向?qū)ο蟮闹匾匦?簡(jiǎn)單點(diǎn)說:“一個(gè)接口,多種實(shí)現(xiàn)”,指一個(gè)基類中派生出了不同的子類,且每個(gè)子類在繼承了同樣的方法名的同時(shí)又對(duì)父類的方法做了不同的實(shí)現(xiàn),這就是同一種事物表現(xiàn)出的多種形態(tài)。
(3)簡(jiǎn)單用法
class?People(object):????#創(chuàng)建一個(gè)類,類名首字母要大寫,并繼承object類def?walk(self):print?"i?am?walking..."def?talk(self):print?"talking?with?sb..."p1?=?People()???#創(chuàng)建一個(gè)對(duì)象,屬于People類 p1.walk()????????#調(diào)用walk方法 p1.talk()p2?=?People() p2.walk() p2.talk()2類的方法
(1)類的方法及屬性
? ?1)類的方法——self
? ?類的方法(類函數(shù))與普通的函數(shù)只有一個(gè)特別的區(qū)別——它們必須有一個(gè)額外的第一個(gè)參數(shù)名稱,但是在調(diào)用這個(gè)方法的時(shí)候你不為這個(gè)參數(shù)賦值,Python會(huì)提供這個(gè)值。這個(gè)特別的變量指對(duì)象本身,按照慣例它的名稱是self。
??如你有一個(gè)類稱為MyClass和這個(gè)類的一個(gè)實(shí)例MyObject。當(dāng)你調(diào)用這個(gè)對(duì)象的方法MyObject.method(arg1, arg2)的時(shí)候,這會(huì)由Python自動(dòng)轉(zhuǎn)為MyClass.method(MyObject, arg1, arg2)
? ?2)__init__()初始化
? ?作用:對(duì)實(shí)體進(jìn)行初始化
? ?如:classDog:
? ? ? def__init__(self,name):
? ? ? self.DogName= name #必須賦值self,否則類中其它函數(shù)無法調(diào)用
(3)類的方法舉例:
class?People(object):info=?'test'??#共享變量,如果實(shí)例變量中找不到時(shí),會(huì)找共享變量def?__init__(self,name,age,job):?#構(gòu)造函數(shù)(實(shí)例化函數(shù))self.name?=?name?#變成實(shí)例變量,即將類的局部變量變?yōu)轭惖娜肿兞縮elf.age?=?ageself.job?=?job#self.info?=?'t2'??#改變info的值def?walk(self):print?"i?am?walking..."def?talk(self):print?"talking?with?sb...",People.infop1?=?People("Dayi",22,"it") p2?=?People("liuyi",24,"itman") p3?=?People("t3",18,"ll")p1.info?=?"P1" print?'P1:',p1.info People.info?=?"haha"???????#如果構(gòu)造函數(shù)中修改了info的值,則此處再無法修改 print?'p2:',p2.info print?'p3:',p3.info(4)析構(gòu)函數(shù)
??在實(shí)例釋放、銷毀的時(shí)候自動(dòng)執(zhí)行的,通常用于做一些收尾工作,如關(guān)閉一些數(shù)據(jù)庫連接,關(guān)閉打開的臨時(shí)文件。
#!/usr/bin/env?python class?Create_role:def?__init__(self,name,age,job):self.name=?nameself.age?=ageself.job?=jobdef?show(self):print("Name:%s?Age:%s?Job:%s"%(self.name,self.age,self.job))def?__del__(self):??#定義一個(gè)析構(gòu)方法print("%s?已經(jīng)徹底清理了"?%(self.name)?)r1?=?Create_role("Dayi",18,"it") print(r1.name) r1.show() del?r1???#在r1調(diào)用結(jié)束后,立即執(zhí)行析構(gòu)方法,默認(rèn)在程序執(zhí)行完成之后才會(huì)執(zhí)行 r2?=?Create_role("xiaoliu",23,"no") r2.show() r3?=?Create_role("hehe",30,"bois")(5)類的私有屬性及私有方法(類的封裝)
? ?python默認(rèn)的成員函數(shù)和成員變量都是公開的。在python中定義私有變量只需要在變量名或函數(shù)名前加上 "__"兩個(gè)下劃線,那么這個(gè)函數(shù)或變量就會(huì)為私有的了。在內(nèi)部,將 __membername替換成 _classname__membername后,你在外部使用原來的私有成員的名字時(shí),會(huì)提示找不到,但是可以在內(nèi)部調(diào)用。
class?People(object):info?=?'test'??#共享變量def?__init__(self,name,age,job):?#構(gòu)造函數(shù)(實(shí)例化函數(shù))self.name?=?name?#變成實(shí)例變量,即將類的局部變量變?yōu)轭惖娜肿兞縮elf.__age?=?age??#定義一個(gè)私有屬性,方法為在屬性名前加__self.job?=?jobself.info?=?'t2'??#改變info的值self.info_dic?=?{"name":'day',"age":"33"}def?get_info(self,info_type):if?info_type?==?'age':return?self.__ageelif?info_type?==?'job':return?self.jobdef?__breath(self):????#定義一個(gè)私有方法,只能在內(nèi)部調(diào)用,創(chuàng)建方法為函數(shù)名前加__print("%s?is?breathing..."?%self.name)def?walk(self):print?"i?am?walking..."print(self.__breath())???????#在內(nèi)部調(diào)用私有方法def?talk(self):print("talking?with?sb...",People.info)p1?=?People("Dayi",22,"it") p2?=?People("liuyi",24,"itman")p1.walk() print(p1.get_info("age")) print(p1._People__age)???#調(diào)用只讀屬性3類的的繼承
? ?Python中類可以承繼父類屬性,也可以同時(shí)繼承多個(gè)父類;形式為class 類名(父類1,父類2),子類可以繼承父類的所有方法和屬性,也可以重載父類的成員函數(shù)及屬性,須注意的是子類成員函數(shù)若重載父類(即名字相同),則會(huì)使用子類成員函數(shù)
(1)類的基本繼承
class?SchoolMember(object):def?__init__(self,name,age,sex):?#創(chuàng)建父類構(gòu)造函數(shù)self.name?=?nameself.age?=?ageself.sex?=?sexdef?tell(self):????#父類創(chuàng)建一個(gè)方法print('''--info?of?%s--name:%sage?:%ssex?:%s'''%(self.name,self.name,self.age,self.sex))class?Student(SchoolMember):????#創(chuàng)建一個(gè)類,并繼承SchoolMemberdef?__init__(self,name,age,sex,grade):???#創(chuàng)建子類繼承函數(shù)SchoolMember.__init__(self,name,age,sex)???#讓子類的構(gòu)造函數(shù)繼承父類self.grade?=?gradedef?pay_money(self):???????#給子類創(chuàng)建一個(gè)方法print("---%s?is?paying?the?tuition?fee---"?%?self.name)def?tell(self):SchoolMember.tell(self)????#讓子類的tell()方法繼承父類print("---from?%s"?%?self.grade) class?Teacher(SchoolMember):def?__init__(self,name,age,sex,course,salary):SchoolMember.__init__(self,name,age,sex)self.course?=?courseself.salary?=?salarydef?teaching(self):print("Teacher?%s?is?teaching?class?of?%s"?%(self.name,self.course))s?=?Student("dayi",33,"M","py?s10") t?=?Teacher("liu",18,"M","python",?60000) s.tell() t.tell() s.pay_money() t.teaching()(2)類的多繼承
? ?1)繼承一:
class?SchoolMember(object):def?__init__(self,name,age,sex):?#創(chuàng)建父類構(gòu)造函數(shù)self.name?=?nameself.age?=?ageself.sex?=?sexdef?tell(self):????#父類創(chuàng)建一個(gè)方法print?'''--info?of?%s--name:%sage?:%ssex?:%s'''%(self.name,self.name,self.age,self.sex) class?School(object):def?__init__(self,name,addr,tel):?#再創(chuàng)建一個(gè)父類構(gòu)造函數(shù)self.school_name?=?nameself.addr?=?addrself.tel?=?telself.stu_list?=?[]self.tech_list?=?[] class?Student(SchoolMember,School):????#創(chuàng)建一個(gè)類,并繼承SchoolMember和School兩個(gè)類def?__init__(self,name,age,sex,grade):???#創(chuàng)建子類繼承函數(shù)SchoolMember.__init__(self,name,age,sex)???#讓子類的構(gòu)造函數(shù)繼承父類School.__init__(self,"beida","shahe",999)?#讓子類的構(gòu)造函數(shù)繼承父類并給傳遞參數(shù)self.grade?=?gradedef?pay_money(self):???????#給子類創(chuàng)建一個(gè)方法print?"---%s?is?paying?the?tuition?fee---"?%?self.namedef?tell(self):SchoolMember.tell(self)????#讓子類的tell()方法繼承父類print?'''---from?school?name?:%sclass?:%saddr??:%s'''%(self.school_name,self.grade,self.addr)s?=?Student("dayi",33,"M","py?s10") s.tell() s.pay_money()2)繼承二(通過super):
class?School(object):def?__init__(self,name,addr):self.name=?nameself.addr=?addrself.students?=[]self.staffs=[]def?enroll(self,stu_obj):print("為學(xué)員%s?辦理注冊(cè)手續(xù)"%stu_obj.name?)self.students.append(stu_obj)def?hire(self,staff_obj):self.staffs.append(staff_obj)print("雇傭新員工%s"?%?staff_obj.name)class?SchoolMember(object):def?__init__(self,name,age,sex):self.name=?nameself.age?=ageself.sex?=sexdef?tell(self):passclass?Teacher(SchoolMember):def?__init__(self,name,age,sex,salary,course):super(Teacher,self).__init__(name,age,sex)self.salary=?salaryself.course=?coursedef?tell(self):print('''----?info?of?Teacher:%s?----Name:%sAge:%sSex:%sSalary:%sCourse:%s'''%(self.name,self.name,self.age,self.sex,self.salary,self.course))def?teach(self):print("%s?is?teaching?course?[%s]"?%(self.name,self.course))class?Student(SchoolMember):def?__init__(self,name,age,sex,stu_id,grade):super(Student,self).__init__(name,age,sex)self.stu_id=?stu_idself.grade=?gradedef?tell(self):print('''----?info?of?Student:%s?----Name:%sAge:%sSex:%sStu_id:%sGrade:%s'''?%?(self.name,?self.name,self.age,?self.sex,?self.stu_id,self.grade))def?pay_tuition(self,amount):print("%s?has?paid?tution?for?$%s"%?(self.name,amount)?)school?=?School("qinghua","海淀")???#為School對(duì)象創(chuàng)建一個(gè)類t1?=?Teacher("day",56,"MF",200000,"Linux") t2?=?Teacher("liu",22,"M",3000,"PythonDevOps")s1?=?Student("dayi123",36,"MF",1001,"PythonDevOps") s2?=?Student("hehe",19,"M",1002,"Linux")t1.tell()????#調(diào)用Teacher類的tell()方法 s1.tell() school.hire(t1) school.enroll(s1) school.enroll(s2)print(school.students) print(school.staffs) school.staffs[0].teach()#獲取staffs列表中的第一個(gè)元素,并調(diào)用Teacher類中的teach方法 #school.students[0].pay_tuition(2000)?for?stu?in?school.students:?????#循環(huán)School類中的student列表的元素并賦值給stustu.pay_tuition(5000)???????#調(diào)用School中的pay_tuition()方法,并傳一個(gè)參數(shù)(3)繼承總結(jié)
? ?py2 經(jīng)典類是按深度優(yōu)先來繼承的,新式類是按廣度優(yōu)先來繼承的
? ?py3 經(jīng)典類和新式類都是統(tǒng)一按廣度優(yōu)先來繼承的
4、多態(tài)(一個(gè)接口、多種實(shí)現(xiàn)):
??多態(tài)意味著就算不知道變量所應(yīng)用的對(duì)象類型是什么,還是能對(duì)他進(jìn)行操作,而它也回根據(jù)對(duì)象(或類)類型的不同而表現(xiàn)出不同的行為。
class?Animal:def?__init__(self,name):??#?Constructor?of?the?classself.name=?namedef?talk(self):??#Abstract?method,?defined?by?convention?onlypass?#raiseNotImplementedError("Subclass?must?implement?abstract?method")@staticmethoddef?animal_talk(obj):???#將調(diào)用方法封裝在父類中obj.talk()class?Cat(Animal):def?talk(self):print('%s?:Meow!'%self.name)class?Dog(Animal):def?talk(self):print('%s:?Woof!?Woof!'%self.name)d?=?Dog("我c") #d.talk()c?=?Cat("小貓貓") #c.talk() # #?def?animal_talk(obj): #?????obj.talk()Animal.animal_talk(c)????#調(diào)用c對(duì)象 Animal.animal_talk(d)5、靜態(tài)方法和類方法
(1)靜態(tài)方法:類的靜態(tài)方法名義上歸類管理,實(shí)際上在靜態(tài)方法里訪問不了類或?qū)嵗械娜魏螌傩?#xff0c;靜態(tài)方法在創(chuàng)建時(shí)被裝入staticmethod類型的對(duì)象中。靜態(tài)方法創(chuàng)建時(shí)沒有self參數(shù),且能夠被類本身直接調(diào)用。
(2)類方法:類方法創(chuàng)建時(shí)被裝入classmethod類型的對(duì)象中,類方法可以直接用類的具體對(duì)象調(diào)用,但類方法只能訪問類變量,不能訪問類的實(shí)例變量。
(3)屬性方法:類的屬性方法可以把一個(gè)類的方法變成一個(gè)類的靜態(tài)屬性。
class?MyClass(object):age?=?22def?__init__(self):self.name=?"hehele"def?sayhi(self):#必須實(shí)例化才能調(diào)用print("---sayhi?1")@staticmethoddef?sayhi2():#靜態(tài)方法,跟類沒甚么關(guān)系,不需要實(shí)例化即可調(diào)用,類的工具包print("---sayhi?2")@staticmethoddef?sayhi2_2(self):#靜態(tài)方法,如果實(shí)在想傳參了,可以這樣搞print("---sayhi?2",self.name)@classmethoddef?sayhi3(self):#不需要實(shí)例化即可調(diào)用,不能訪問實(shí)例數(shù)據(jù),?訪問了實(shí)例化中的數(shù)據(jù)(self.name)調(diào)用時(shí)會(huì)報(bào)錯(cuò)。print("---sayhi?3",self.age,self.name)@property#將函數(shù)變成靜態(tài)屬性def?sayhi4(self):print("---sayhi?4",self.name)return?'test'm?=?MyClass() m.sayhi2() m.sayhi2_2(m)????#調(diào)用時(shí)將參數(shù)給參進(jìn)去 print(m.sayhi4) #?m.sayhi3() #?MyClass.sayhi3()類的屬性方法應(yīng)用:
class?Attribute(object):def?__init__(self,name):self.name=?nameself.__food=?None@property?????#將類的方法變成類的靜態(tài)屬性def?eat(self):print("%s?eating?%s......"?%(self.name,self.__food))@eat.setter???#修改屬性def?eat(self,food):print("set?to?food:",food)self.__food=?food@eat.deleterdef?eat(self):??#刪除屬性del?self.__food d?=?Attribute("dayi") #?print(d.__dict__) d.eat d.eat?=?"noodle" d.eat??????#修改屬性后調(diào)用屬性 del?d.eat????#刪除屬性 d.eat????????#刪除時(shí)調(diào)用屬性會(huì)報(bào)錯(cuò)6、類的成員方法
(1)__doc__
??作用:獲取類的描述信息
class?Dayi():"""welcome?to?...."""def?func(self):"""func"""pass print(Dayi.__doc__)???#會(huì)打印class的描述信息(2)__module__
??作用:表示當(dāng)前操作的對(duì)象在那個(gè)模塊
? ?__class__
??作用:表示當(dāng)前操作的對(duì)象的類是什么
from?lib?import?Dayi tim?=?Dayiprint(tim.__module__) print(tim.__class__)(3)__call__
??作用:構(gòu)造方法的執(zhí)行是由創(chuàng)建對(duì)象觸發(fā)的,即:對(duì)象 = 類名() ;而對(duì)于__call__ 方法的執(zhí)行是由對(duì)象后加括號(hào)觸發(fā)的,即:對(duì)象() 或者 類()()
class?Call():def?__init__(self):passdef?__call__(self,?*args,?**kwargs):print("__call__")obj?=?Call()????#執(zhí)行__init__ obj()???????????#執(zhí)行__call__(4)__dict__
??作用:查看類或?qū)ο笾械乃谐蓡T,以字典的形式顯示,
(5)__str__
??作用:如果一個(gè)類中定義了__str__方法,那么在打印 對(duì)象 時(shí),默認(rèn)輸出該方法的返回值
class?Dayi(object):def?dayi123(self):print("dayi123")def?__str__(self):return?"hello"obj?=?Dayi() print(obj)???#沒有__str__時(shí)輸出類的內(nèi)存地址,有__str__時(shí),輸出值(6)__getitem__、__setitem__、__delitem__
??作用:用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)
class?Foo(object):def?__init__(self):self.data?=?{}def?__getitem__(self,?key):print('__getitem__',?key)return?self.data.get(key)???#讀取字典中key的值def?__setitem__(self,?key,?value):print('__setitem__',?key,?value)self.data[key]?=?value???????#設(shè)置字典中keydef?__delitem__(self,?key):print('__delitem__',?key)del?self.data[key]?#刪除data中的為key的數(shù)據(jù)obj?=?Foo() obj['name']?=?"hehe" print(obj.__dict__) print(obj.data) #?del?obj["name"]????#刪除時(shí)自動(dòng)觸發(fā)__delitem__ result?=?obj['k1']??#?自動(dòng)觸發(fā)執(zhí)行?__getitem__ print(obj.__dict__) obj['k2']?=?'kk2'??#?自動(dòng)觸發(fā)執(zhí)行?__setitem__ print(obj.__dict__)??#查看類的字典時(shí),類的字典內(nèi)容為{'data':?{'k2':?'kk2',?'name':?'hehe'}} del?obj['k2'] print(obj.__dict__)轉(zhuǎn)載于:https://blog.51cto.com/dayi123/1925661
總結(jié)
以上是生活随笔為你收集整理的Python中面向对象的编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NHibernate利用Mindscap
- 下一篇: 开发原生的 Google 眼镜应用 【已