開心檔之Python3 面向對象

Python3 面向對象

Python從設計之初就已經(jīng)是一門面向對象的語言奥吩,正因為如此捂敌,在Python中創(chuàng)建一個類和對象是很容易的。本章節(jié)我們將詳細介紹Python的面向對象編程碍拆。

如果你以前沒有接觸過面向對象的編程語言奔脐,那你可能需要先了解一些面向對象語言的一些基本特征躯舔,在頭腦里頭形成一個基本的面向對象的概念,這樣有助于你更容易的學習Python的面向對象編程滞谢。

接下來我們先來簡單的了解下面向對象的一些基本特征。

面向對象技術簡介

**類(Class):**用來描述具有相同的屬性和方法的對象的集合除抛。它定義了該集合中每個對象所共有的屬性和方法爹凹。對象是類的實例。

**方法:**類中定義的函數(shù)镶殷。

**類變量:**類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數(shù)體之外微酬。類變量通常不作為實例變量使用绘趋。

**數(shù)據(jù)成員:**類變量或者實例變量用于處理類及其實例對象的相關的數(shù)據(jù)。

**方法重寫:**如果從父類繼承的方法不能滿足子類的需求颗管,可以對其進行改寫陷遮,這個過程叫方法的覆蓋(override),也稱為方法的重寫垦江。

**局部變量:**定義在方法中的變量帽馋,只作用于當前實例的類。

**實例變量:**在類的聲明中比吭,屬性是用變量來表示的绽族,這種變量就稱為實例變量,實例變量就是一個用 self 修飾的變量衩藤。

**繼承:**即一個派生類(derived class)繼承基類(base class)的字段和方法吧慢。繼承也允許把一個派生類的對象作為一個基類對象對待。例如赏表,有這樣一個設計:一個Dog類型的對象派生自Animal類检诗,這是模擬"是一個(is-a)"關系(例圖,Dog是一個Animal)瓢剿。

**實例化:**創(chuàng)建一個類的實例逢慌,類的具體對象。

**對象:**通過類定義的數(shù)據(jù)結構實例间狂。對象包括兩個數(shù)據(jù)成員(類變量和實例變量)和方法攻泼。

和其它編程語言相比,Python 在盡可能不增加新的語法和語義的情況下加入了類機制前标。

Python中的類提供了面向對象編程的所有基本功能:類的繼承機制允許多個基類坠韩,派生類可以覆蓋基類中的任何方法,方法中可以調用基類中的同名方法炼列。

對象可以包含任意數(shù)量和類型的數(shù)據(jù)只搁。

類定義

語法格式如下:

classClassName:.? ? .? ? .? ?

類實例化后,可以使用其屬性俭尖,實際上氢惋,創(chuàng)建一個類之后洞翩,可以通過類名訪問其屬性。

類對象

類對象支持兩種操作:屬性引用和實例化焰望。

屬性引用使用和 Python 中所有的屬性引用一樣的標準語法:obj.name骚亿。

類對象創(chuàng)建后,類命名空間中所有的命名都是有效屬性名熊赖。所以如果類定義是這樣:

實例(Python 3.0+)

#!/usr/bin/python3classMyClass:"""一個簡單的類實例"""i =12345deff(self):return'hello world'# 實例化類x = MyClass()# 訪問類的屬性和方法print("MyClass 類的屬性 i 為:", x.i)print("MyClass 類的方法 f 輸出為:", x.f())

以上創(chuàng)建了一個新的類實例并將該對象賦給局部變量 x来屠,x 為空的對象。

執(zhí)行以上程序輸出結果為:

MyClass類的屬性 i 為:12345MyClass類的方法 f 輸出為: hello world

類有一個名為?init() 的特殊方法(構造方法)震鹉,該方法在類實例化時會自動調用俱笛,像下面這樣:

def__init__(self):self.data = []

類定義了?init() 方法旁仿,類的實例化操作會自動調用?init() 方法汰瘫。如下實例化類 MyClass,對應的?init() 方法就會被調用:

x= MyClass()

當然神妹,?init() 方法可以有參數(shù)浆兰,參數(shù)通過?init() 傳遞到類的實例化操作上磕仅。例如:

實例(Python 3.0+)

#!/usr/bin/python3classComplex:def__init__(self, realpart, imagpart):? ? ? ? self.r = realpart? ? ? ? self.i = imagpartx = Complex(3.0, -4.5)print(x.r, x.i)# 輸出結果:3.0 -4.5

self代表類的實例,而非類

類的方法與普通的函數(shù)只有一個特別的區(qū)別------它們必須有一個額外的第一個參數(shù)名稱, 按照慣例它的名稱是 self簸呈。

classTest:defprt(self):print(self)print(self.__class__) t = Test()t.prt()

以上實例執(zhí)行結果為:

<__main__.Testinstanceat0x100771878>__main__.Test

從執(zhí)行結果可以很明顯的看出榕订,self 代表的是類的實例,代表當前對象的地址蝶棋,而 self.class 則指向類卸亮。

self 不是 python 關鍵字,我們把他換成 kxdang 也是可以正常執(zhí)行的:

class Test:? ? defprt(kxdang):print(kxdang)print(kxdang.__class__) t =Test()t.prt()

以上實例執(zhí)行結果為:

<__main__.Testinstanceat0x100771878>__main__.Test

類的方法

在類的內(nèi)部玩裙,使用 def 關鍵字來定義一個方法兼贸,與一般函數(shù)定義不同,類方法必須包含參數(shù) self, 且為第一個參數(shù)吃溅,self 代表的是類的實例溶诞。

實例(Python 3.0+)

#!/usr/bin/python3#類定義classpeople:#定義基本屬性name =''age =0#定義私有屬性,私有屬性在類外部無法直接進行訪問__weight =0#定義構造方法def__init__(self,n,a,w):? ? ? ? self.name = n? ? ? ? self.age = a? ? ? ? self.__weight = wdefspeak(self):print("%s 說: 我 %d 歲。"%(self.name,self.age))# 實例化類p = people('kxdang',10,30)p.speak()

執(zhí)行以上程序輸出結果為:

kxdang 說: 我 10 歲决侈。

繼承

Python 同樣支持類的繼承螺垢,如果一種語言不支持繼承,類就沒有什么意義赖歌。派生類的定義如下所示:

class DerivedClassName(BaseClassName):.? ? .? ? .

子類(派生類 DerivedClassName)會繼承父類(基類 BaseClassName)的屬性和方法枉圃。 BaseClassName(實例中的基類名)必須與派生類定義在一個作用域內(nèi)。除了類庐冯,還可以用表達式孽亲,基類定義在另一個模塊中時這一點非常有用:

classDerivedClassName(modname.BaseClassName):

實例(Python 3.0+)

#!/usr/bin/python3#類定義classpeople:#定義基本屬性name =''age =0#定義私有屬性,私有屬性在類外部無法直接進行訪問__weight =0#定義構造方法def__init__(self,n,a,w):? ? ? ? self.name = n? ? ? ? self.age = a? ? ? ? self.__weight = wdefspeak(self):print("%s 說: 我 %d 歲。"%(self.name,self.age))#單繼承示例classstudent(people):? ? grade =''def__init__(self,n,a,w,g):#調用父類的構函people.__init__(self,n,a,w)? ? ? ? self.grade = g#覆寫父類的方法defspeak(self):print("%s 說: 我 %d 歲了展父,我在讀 %d 年級"%(self.name,self.age,self.grade))? s = student('ken',10,60,3)s.speak()

執(zhí)行以上程序輸出結果為:

ken 說: 我 10 歲了返劲,我在讀 3 年級

多繼承

Python同樣有限的支持多繼承形式玲昧。多繼承的類定義形如下例:

class DerivedClassName(Base1, Base2, Base3):.? ? .? ? .

需要注意圓括號中父類的順序,若是父類中有相同的方法名篮绿,而在子類使用時未指定孵延,python從左至右搜索 即方法在子類中未找到時,從左到右查找父類中是否包含方法亲配。

實例(Python 3.0+)

#!/usr/bin/python3#類定義classpeople:#定義基本屬性name =''age =0#定義私有屬性,私有屬性在類外部無法直接進行訪問__weight =0#定義構造方法def__init__(self,n,a,w):? ? ? ? self.name = n? ? ? ? self.age = a? ? ? ? self.__weight = wdefspeak(self):print("%s 說: 我 %d 歲尘应。"%(self.name,self.age))#單繼承示例classstudent(people):? ? grade =''def__init__(self,n,a,w,g):#調用父類的構函people.__init__(self,n,a,w)? ? ? ? self.grade = g#覆寫父類的方法defspeak(self):print("%s 說: 我 %d 歲了,我在讀 %d 年級"%(self.name,self.age,self.grade))#另一個類吼虎,多重繼承之前的準備classspeaker():? ? topic =''name =''def__init__(self,n,t):? ? ? ? self.name = n? ? ? ? self.topic = tdefspeak(self):print("我叫 %s菩收,我是一個演說家,我演講的主題是 %s"%(self.name,self.topic))#多重繼承classsample(speaker,student):? ? a =''def__init__(self,n,a,w,g,t):? ? ? ? student.__init__(self,n,a,w,g)? ? ? ? speaker.__init__(self,n,t) test = sample("Tim",25,80,4,"Python")test.speak()#方法名同鲸睛,默認調用的是在括號中參數(shù)位置排前父類的方法

執(zhí)行以上程序輸出結果為:

我叫 Tim,我是一個演說家坡贺,我演講的主題是 Python

方法重寫

如果你的父類方法的功能不能滿足你的需求官辈,你可以在子類重寫你父類的方法,實例如下:

實例(Python 3.0+)

#!/usr/bin/python3classParent:# 定義父類defmyMethod(self):print('調用父類方法')classChild(Parent):# 定義子類defmyMethod(self):print('調用子類方法') c = Child()# 子類實例c.myMethod()# 子類調用重寫方法super(Child,c).myMethod()#用子類對象調用父類已被覆蓋的方法

super() 函數(shù)是用于調用父類(超類)的一個方法遍坟。

執(zhí)行以上程序輸出結果為:

調用子類方法

調用父類方法

更多文檔:

Python 子類繼承父類構造函數(shù)說明

類屬性與方法

類的私有屬性

__private_attrs?:兩個下劃線開頭拳亿,聲明該屬性為私有,不能在類的外部被使用或直接訪問愿伴。在類內(nèi)部的方法中使用時?self.__private_attrs肺魁。

類的方法

在類的內(nèi)部,使用 def 關鍵字來定義一個方法隔节,與一般函數(shù)定義不同鹅经,類方法必須包含參數(shù) self,且為第一個參數(shù)怎诫,self 代表的是類的實例瘾晃。

self 的名字并不是規(guī)定死的,也可以使用 this幻妓,但是最好還是按照約定使用 self蹦误。

類的私有方法

__private_method?:兩個下劃線開頭,聲明該方法為私有方法肉津,只能在類的內(nèi)部調用 强胰,不能在類的外部調用。self.__private_methods妹沙。

實例

類的私有屬性實例如下:

實例(Python 3.0+)

#!/usr/bin/python3classJustCounter:? ? __secretCount =0# 私有變量publicCount =0# 公開變量defcount(self):? ? ? ? self.__secretCount +=1self.publicCount +=1print(self.__secretCount) counter = JustCounter()counter.count()counter.count()print(counter.publicCount)print(counter.__secretCount)# 報錯偶洋,實例不能訪問私有變量

執(zhí)行以上程序輸出結果為:

122Traceback (most recent calllast):? File"test.py", line16, in print(counter.__secretCount)# 報錯,實例不能訪問私有變量AttributeError:'JustCounter'object hasnoattribute'__secretCount'

類的私有方法實例如下:

實例(Python 3.0+)

#!/usr/bin/python3classSite:def__init__(self, name, url):? ? ? ? self.name = name# publicself.__url = url# privatedefwho(self):print('name? : ', self.name)print('url : ', self.__url)def__foo(self):# 私有方法print('這是私有方法')deffoo(self):# 公共方法print('這是公共方法')? ? ? ? self.__foo() x = Site('菜鳥教程','www.kxdang.com/topic/')x.who()# 正常輸出x.foo()# 正常輸出x.__foo()# 報錯

以上實例執(zhí)行結果:

類的專有方法:

init?:?構造函數(shù)初烘,在生成對象時調用

del?:?析構函數(shù)涡真,釋放對象時使用

repr?:?打印分俯,轉換

setitem?:?按照索引賦值

getitem:?按照索引獲取值

len:?獲得長度

cmp:?比較運算

call:?函數(shù)調用

add:?加運算

sub:?減運算

mul:?乘運算

truediv:?除運算

mod:?求余運算

pow:?乘方

運算符重載

Python同樣支持運算符重載,我們可以對類的專有方法進行重載哆料,實例如下:

實例(Python 3.0+)

#!/usr/bin/python3classVector:def__init__(self, a, b):? ? ? self.a = a? ? ? self.b = bdef__str__(self):return'Vector (%d, %d)'% (self.a, self.b)def__add__(self,other):returnVector(self.a + other.a, self.b + other.b) v1 = Vector(2,10)v2 = Vector(5,-2)print(v1 + v2)

以上代碼執(zhí)行結果如下所示:

Vector(7,8)

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缸剪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子东亦,更是在濱河造成了極大的恐慌杏节,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件典阵,死亡現(xiàn)場離奇詭異奋渔,居然都是意外死亡,警方通過查閱死者的電腦和手機壮啊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門嫉鲸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人歹啼,你說我怎么就攤上這事玄渗。” “怎么了狸眼?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵藤树,是天一觀的道長。 經(jīng)常有香客問我拓萌,道長岁钓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任微王,我火速辦了婚禮屡限,結果婚禮上,老公的妹妹穿的比我還像新娘炕倘。我一直安慰自己囚霸,他們只是感情好,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布激才。 她就那樣靜靜地躺著拓型,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘸恼。 梳的紋絲不亂的頭發(fā)上劣挫,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音东帅,去河邊找鬼压固。 笑死,一個胖子當著我的面吹牛靠闭,可吹牛的內(nèi)容都是我干的帐我。 我是一名探鬼主播坎炼,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拦键!你這毒婦竟也來了谣光?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤芬为,失蹤者是張志新(化名)和其女友劉穎萄金,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體媚朦,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡氧敢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了询张。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孙乖。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖份氧,靈堂內(nèi)的尸體忽然破棺而出的圆,到底是詐尸還是另有隱情,我是刑警寧澤半火,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站季俩,受9級特大地震影響钮糖,放射性物質發(fā)生泄漏。R本人自食惡果不足惜酌住,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一店归、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酪我,春花似錦消痛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至欺矫,卻和暖如春纱新,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背穆趴。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工脸爱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人未妹。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓簿废,卻偏偏與公主長得像空入,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子族檬,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容