Python面向?qū)ο笾?lèi)和對(duì)象實(shí)例詳解
本文實(shí)例講述了Python面向?qū)ο笾?lèi)和對(duì)象。分享給大家供大家參考,具體如下:
類(lèi)和對(duì)象(1)
對(duì)象是什么?
對(duì)象=屬性(靜態(tài))+方法(動(dòng)態(tài));
屬性一般是一個(gè)個(gè)變量;方法是一個(gè)個(gè)函數(shù);
#類(lèi)的屬性 就是 類(lèi)變量
#實(shí)例變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類(lèi)。
例子:
class Turtle:#python 中類(lèi)名約定以大寫(xiě)字母開(kāi)頭 '''關(guān)于類(lèi)的簡(jiǎn)單例子。。。''' #屬性 == 類(lèi)變量 color ="green" weight="10kg" legs=4 shell=True mouth='big' #方法 def climb(self): self.name = "test" #實(shí)例變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類(lèi)。 print("我在很努力爬。") def run(self): print('我在很努力跑。') def bite(self): print('我要要要要要') def sleep(self): print('我要睡覺(jué)啦。') #創(chuàng)建一個(gè)實(shí)例對(duì)象也就是類(lèi)的實(shí)例化! tt =Turtle() #類(lèi)的實(shí)例化,也就是創(chuàng)建一個(gè)對(duì)象,類(lèi)名約定大寫(xiě)字母開(kāi)頭 tt.bite() #創(chuàng)建好類(lèi)后就能調(diào)用類(lèi)里面的方法叻; tt.sleep()
面向?qū)ο蟮奶卣鳎?/strong>
oo = Object Oriented(面向?qū)ο螅?/code>
1.封裝(信息隱蔽技術(shù))
python的列表list其實(shí)就是一個(gè)對(duì)象,它提供了很多方法:sort()、append()
封裝后就可以直接調(diào)用里面的方法了?。?!
2.繼承
子類(lèi)自動(dòng)共享父類(lèi)之間數(shù)據(jù)和方法的機(jī)制。
class MyList(list):#創(chuàng)建一個(gè)類(lèi)繼承l(wèi)ist的所有方法和屬性 pass #相當(dāng)于一個(gè)占位符 list1=MyList() #類(lèi)實(shí)例化 list1.append(1) #繼承后調(diào)用list的方法append()
3.多態(tài)
不同對(duì)象對(duì)同一方法響應(yīng)不同行動(dòng)。就是名字一樣方法不一樣:
>>> class A: def fun(self): print('aaaa') >>>class B (): def fun(self): print('bbb') >>> a=A() >>>b=B() >>>a.fun() aaaa >>>b.fun() bbb
類(lèi)和對(duì)象(2)
self是什么?
如果把類(lèi)當(dāng)做圖紙,那么由類(lèi)實(shí)例化后的對(duì)象就是可以住人的房子。self就相當(dāng)于房子的門(mén)牌號(hào),由self就可以找到對(duì)象。
一個(gè)類(lèi)可以生成無(wú)數(shù)個(gè)對(duì)象,對(duì)象之間都很相似,因?yàn)槎际莵?lái)源與類(lèi)的方法屬性。當(dāng)對(duì)象方法被調(diào)用時(shí),對(duì)象就會(huì)將自己作為第一個(gè)參數(shù)傳給self,python就是根據(jù)self知道哪一個(gè)對(duì)象在調(diào)用方法;
>>>class Ball(): def setname(self,name): self.name=name def kick (self): print("我叫%r,誰(shuí)踢我"%self.name) >>>a=Ball() 實(shí)例化生成a對(duì)象 >>>a.setname('a') 調(diào)用方法設(shè)名為a >>>b=Ball() >>>b.setname('b') >>>c=Ball() >>>c.setname() >>>a.kick () 通過(guò)self知道是哪個(gè)對(duì)象調(diào)用kick方法 我叫'a',誰(shuí)踢我 >>>b.kick() 我叫'b',誰(shuí)踢我
python的魔法方法:
__init__(self)
這個(gè)是構(gòu)造方法。
實(shí)例化一個(gè)對(duì)象時(shí),這個(gè)方法就會(huì)在對(duì)象創(chuàng)建時(shí)(實(shí)例化類(lèi)就是創(chuàng)建對(duì)象)自動(dòng)調(diào)用。實(shí)例化時(shí)就會(huì)調(diào)用__init__(self)
這個(gè)方法。
實(shí)例化對(duì)象是可以傳入?yún)?shù)的,這些參數(shù)被傳入init方法中,可通過(guò)重寫(xiě)方法來(lái)自定義對(duì)象初始化操作。
>>>class Ball: def __init__(self,name): self.name = name def kick(self): print('我叫%r,誰(shuí)踢我'%self.name) >>> b=Ball('b') #創(chuàng)建對(duì)象,這時(shí)__init__(self):就被調(diào)用了,可以傳入b >>>b.kick() 我叫'b',誰(shuí)踢我
公有和私有:
公有和私有數(shù)據(jù)類(lèi)型。python中對(duì)象的屬性和方法都是公開(kāi)的都是公有的通過(guò).操作符訪問(wèn)。
python中定義私有變量只需在變量名或函數(shù)名前增加兩個(gè)下劃線(xiàn)‘__',那么這個(gè)函數(shù)、變量變?yōu)樗降牧恕?/p>
>>> class P(): __name="liyue" #私有變量,外部不能通過(guò).操作符直接訪問(wèn)了
類(lèi)和對(duì)象(3):繼承
語(yǔ)法:
class A(B): ………….
B我們叫父類(lèi)、基類(lèi)或超類(lèi);
A我們叫子類(lèi),子類(lèi)繼承父類(lèi)的屬性和方法;
例子:
>>> class Parent(): defhello(self): print("helloliyue!") >>> class Child(Parent): pass >>> p=Parent() >>> p.hello() hello liyue! >>> c=Child() >>> c.hello() hello liyue!
注意:如果子類(lèi)中定義與父類(lèi)同名的方法或?qū)傩?,則會(huì)自動(dòng)覆蓋父類(lèi)對(duì)應(yīng)的方法或?qū)傩浴?/p>
例子:
>>> class Parent(): defhello(self): print("helloliyue!") >>> class Child(Parent): defhello(self): print("hahah!") >>> p=Parent() >>>p.hello () hello liyue! >>> c =Child() >>>c.hello () #子類(lèi)和父類(lèi)方法相同,(子類(lèi)重寫(xiě)父類(lèi)方法)會(huì)覆蓋父類(lèi)方法,但是父類(lèi)自己的方法不變 hahah!
super()
函數(shù):解決了子類(lèi)就算重寫(xiě)父類(lèi)方法或?qū)傩匀匀豢梢岳^續(xù)使用父類(lèi)的方法和屬性。
具體實(shí)例及說(shuō)明:
import random as r #利用繼承演示魚(yú)游動(dòng)方向位置。 class Fish(): #父類(lèi) def __init__(self): self.x =r.randint(0,10) self.y =r.randint(0,10) def move(self): self.x -=1 #一直向西移動(dòng) print("我的位置是:",self.x,self.y) classGoldfish(Fish): #子類(lèi) pass classCarp(Fish): #子類(lèi) pass classSalmon(Fish): #子類(lèi) pass classShark(Fish): def __init__(self): #這里重寫(xiě)了__init__方法,就會(huì)覆蓋掉父類(lèi)的方法了,用到super函數(shù)后就可以繼續(xù)使用父類(lèi)的方法。 #super函數(shù)不用給定任何基類(lèi)的名字(如下),它會(huì)一層層找出代碼所有父類(lèi)里面對(duì)應(yīng)的方法,要改變?cè)擃?lèi)的繼承關(guān)系時(shí)只需修改這個(gè)類(lèi)的父類(lèi)就行就是括號(hào)里面的Fish。 super().__init__() #super().重寫(xiě)的屬性或方法 self.hungry = True def eat(self): if self.hungry: print("我要吃了。。。") self.hungry = False else: print('好飽了。。。') >>> f=Fish() >>>f.move() 我的位置是: -1 3 >>>f.move() 我的位置是: -2 3 >>>g=Goldfish() >>>g.move() 我的位置是: 4 4 >>>s=Salmon() >>>s.move() 我的位置是: 8 1 >>>s.move() 我的位置是: 7 1 >>> s=Shark() >>>s.eat() 我要吃了。。。 >>>s.eat() 好飽了。。。 >>>s.move() 我的位置是: 5 10 #這就是子類(lèi)就可以使用父類(lèi)的move()方法 >>>s.move() 我的位置是: 4 10
類(lèi)和對(duì)象(4)
1.組合:一般把幾個(gè)沒(méi)有什么關(guān)系的類(lèi)放在一起使用時(shí)通過(guò)組合類(lèi)的方法。
例子:要求定義一個(gè)類(lèi),叫水池,水池里面有烏龜和魚(yú)。
class Turtle(): #定義烏龜類(lèi) def __init__(self,x): self.num = x classFish(): #定義魚(yú)類(lèi) def __init__(self,y): self.num = y classPool(): #定義水池類(lèi) def __init__(self,x,y): self.turtle = Turtle(x) #直接把需要的類(lèi)在這里實(shí)例化就行了,組合實(shí)現(xiàn) self.fish = Fish(y) def print_num(self): print("水池中總共有烏龜%d只,小魚(yú)%r條。"%(self.turtle.num,self.fish.num) >>> p =Pool(1,10) >>>p.print_num () 水池中總共有烏龜1只,小魚(yú)10條
這就是組合,組合就是把類(lèi)的實(shí)例化放到一個(gè)新類(lèi)里面,他就把舊類(lèi)組合進(jìn)去了。
組合一般就是說(shuō)把幾個(gè)不是有繼承關(guān)系的、沒(méi)有直線(xiàn)關(guān)系的幾個(gè)類(lèi)放在一起,如果要實(shí)現(xiàn)縱向關(guān)系的幾個(gè)類(lèi),就是繼承。
2.類(lèi)、類(lèi)對(duì)象、實(shí)例對(duì)象
>>>class C(): #類(lèi),當(dāng)類(lèi)寫(xiě)完后就變成了類(lèi)對(duì)象 def x(self): print("xaaa") >>> c =C() #c是實(shí)例對(duì)象,C()是類(lèi)對(duì)象 >>> c.x() xaaa >>> c.x= 1 #實(shí)例對(duì)象初始化一個(gè)變量 >>> c.x 1 >>> c.x() #就不能繼續(xù)調(diào)用原來(lái)的方法了,同名會(huì)覆蓋掉類(lèi)的方法 Traceback (most recent call last): File"<pyshell#18>", line 1, in <module> c.x() TypeError: 'int' object is not callable
所以:不要試圖在一個(gè)類(lèi)里面定義所有的屬性和方法,應(yīng)該利用繼承和組合機(jī)制;
用不同的詞性命名,如屬性名用名詞,方法名用動(dòng)詞。
3.什么是綁定?
python嚴(yán)格要求方法需要有實(shí)例才能被調(diào)用,這種限制其實(shí)就是綁定。
>>>class CC: #類(lèi) def setxy(self,x,y): self.x = x self.y = y def printxy(self): print(self.x,self.y) >>> dd= CC() #實(shí)例對(duì)象,類(lèi)對(duì)象 >>>dd.__dict__ #查看實(shí)例對(duì)象所擁有的屬性 {} >>>CC.__dict__ #查看類(lèi)對(duì)象所擁有的屬性 mappingproxy({'setxy':<function CC.setxy at 0x00000000031F9B70>, 'printxy': <functionCC.printxy at 0x00000000031F9BF8>, '__module__': '__main__', '__weakref__':<attribute '__weakref__' of 'CC' objects>, '__dict__': <attribute '__dict__'of 'CC' objects>, '__doc__': None}) >>>dd.setxy (4,5) #實(shí)例對(duì)象中傳入x,y >>>dd.__dict__ #實(shí)例對(duì)象就有屬性了,這兩個(gè)屬性緊屬于實(shí)例對(duì)象的,類(lèi)對(duì)象中是沒(méi)有的 {'y': 5, 'x': 4} #類(lèi)對(duì)象中是沒(méi)有實(shí)例對(duì)象傳入的,這歸功與綁定這個(gè)功能,self
為什么實(shí)例對(duì)象調(diào)用方法后類(lèi)對(duì)象中沒(méi)有實(shí)例對(duì)象的屬性?
實(shí)例對(duì)象調(diào)用方法時(shí),dd.setxy(dd,4,5) 實(shí)際上是這樣的,也就是(self.x = x;self.y = y)dd.x=4,dd.y=5,那么4,5存放在實(shí)例對(duì)象的空間,故這兩個(gè)屬性只屬于實(shí)例對(duì)象的。(實(shí)例對(duì)象調(diào)用類(lèi)方法時(shí),先把自己傳給self,self.x也就是dd.x.)
類(lèi)對(duì)象與實(shí)例對(duì)象差別:
把類(lèi)對(duì)象CC刪除后,del CC,再實(shí)例化就會(huì)報(bào)錯(cuò),但是已經(jīng)實(shí)例化對(duì)象dd仍然可以調(diào)用類(lèi)對(duì)象中的方法:
>>> delCC >>>dd.setxy (3,4) >>>dd.__dict__ {'y': 4, 'x': 3} >>> dd =CC() Traceback (most recent call last): File"<pyshell#45>", line 1, in <module> dd =CC() NameError: name 'CC' is not defined >>>dd.printxy () 3 4
為什么已經(jīng)實(shí)例化對(duì)象dd仍然可以調(diào)用類(lèi)對(duì)象中的方法?
類(lèi)中定義的屬性是靜態(tài)變量,方法也一樣,就算類(lèi)對(duì)象被刪除了,屬性和方法一樣存放在內(nèi)存中,故實(shí)例對(duì)象仍然可以從內(nèi)存中調(diào)用類(lèi)的方法和屬性,除非程序退出。所以創(chuàng)建一個(gè)類(lèi)后最好先實(shí)例化再使用類(lèi)對(duì)象中的方法,不要直接利用類(lèi)對(duì)象調(diào)用方法。
self.x self相當(dāng)于實(shí)例對(duì)象的名字,.x就是實(shí)例的空間了
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門(mén)與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- Python入門(mén)篇之面向?qū)ο?/a>
- Python面向?qū)ο笾蓄?lèi)(class)的簡(jiǎn)單理解與用法分析
- Python 使用 attrs 和 cattrs 實(shí)現(xiàn)面向?qū)ο缶幊痰膶?shí)踐
- Python 面向?qū)ο?成員的訪問(wèn)約束
- Python面向?qū)ο髮?shí)現(xiàn)一個(gè)對(duì)象調(diào)用另一個(gè)對(duì)象操作示例
- Python3.5面向?qū)ο缶幊虉D文與實(shí)例詳解
- Python中的面向?qū)ο缶幊淘斀?上)
- Python面向?qū)ο箢?lèi)的繼承實(shí)例詳解
- Python?面向?qū)ο缶幊淘斀?/a>
相關(guān)文章
python操作excel的包(openpyxl、xlsxwriter)
這篇文章主要為大家詳細(xì)介紹了python操作excel的包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06tensorflow 重置/清除計(jì)算圖的實(shí)現(xiàn)
今天小編就為大家分享一篇tensorflow 重置/清除計(jì)算圖的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01python刪除過(guò)期log文件操作實(shí)例解析
這篇文章主要介紹了python刪除過(guò)期log文件,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01django inspectdb 操作已有數(shù)據(jù)庫(kù)數(shù)據(jù)的使用步驟
這篇文章主要介紹了django inspectdb 操作已有數(shù)據(jù)庫(kù)數(shù)據(jù)的使用步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Python?不設(shè)計(jì)?do-while?循環(huán)結(jié)構(gòu)的理由
Python作為一種語(yǔ)言不支持do-while循環(huán)。?但是,我們可以采用一種變通方法來(lái)模擬do-while循環(huán)?。下面通過(guò)本文給大家分享下Python?不設(shè)計(jì)do-while?循環(huán)結(jié)構(gòu)的理由,需要的朋友可以參考下2022-01-01