|
作者 | Radek Fabisiak 譯者 | 彎月,責(zé)編 | 郭芮 出品 | CSDN(ID:CSDNnews) 現(xiàn)如今面向?qū)ο缶幊痰氖褂梅浅V泛,本文我們就來(lái)探討一下Python中的面向?qū)ο缶幊獭?/span> 以下為譯文: Python支持多種類型的編程范式,例如過(guò)程式編程、函數(shù)式編程、面向?qū)ο缶幊?,而且還可以融合多種類型的范式。 現(xiàn)如今面向?qū)ο缶幊痰氖褂梅浅V泛。面向?qū)ο缶幊痰幕驹厥菍?duì)象,其包含的數(shù)據(jù)成員稱為屬性,函數(shù)(例程、過(guò)程)稱為方法。 對(duì)象是類的實(shí)例。換句話說(shuō),類主要定義對(duì)象的結(jié)構(gòu),然后我們以類為模板創(chuàng)建對(duì)象。類不但包含方法定義,而且還包含所有實(shí)例共享的數(shù)據(jù)。 本文我們來(lái)探討一下Python中的面向?qū)ο缶幊?。我們將演示如何?chuàng)建類,并使用類來(lái)實(shí)例化對(duì)象。本文的主要內(nèi)容如下:
本文無(wú)法涵蓋這些主題的所有詳細(xì)信息。Python中的面向?qū)ο缶幊踢€包含其他很多方面。希望本文能夠?yàn)槟銓W(xué)習(xí)Python及實(shí)現(xiàn)面向?qū)ο筇峁┮粋€(gè)良好的開端。 創(chuàng)建Python類 我們可以使用關(guān)鍵字class定義Python類,關(guān)鍵字后面緊跟類的名稱、分號(hào)和類的實(shí)現(xiàn):
按照慣例,Python類的命名采用首字母大寫(即PascalCase)。 現(xiàn)在讓我們創(chuàng)建這個(gè)新類的一個(gè)實(shí)例,名為MyClass:
語(yǔ)句a = MyClass()創(chuàng)建了MyClass的一個(gè)實(shí)例,并將它的引用賦值給變量a。 我們可以通過(guò)Python內(nèi)置的函數(shù)type()或直接通過(guò)屬性.__class__來(lái)獲取類型(即對(duì)象的類)。在拿到類(類型)之后,我們就可以利用屬性.__ name__獲取類的名字:
順便提一句,Python類也是對(duì)象。它們是type的實(shí)例:
下面,我們來(lái)定義一個(gè)方法。 Python中每個(gè)實(shí)例方法的第一個(gè)參數(shù)必須對(duì)應(yīng)于該實(shí)例,即該對(duì)象本身。按照慣例,這個(gè)參數(shù)名為self。后面是其他參數(shù)(如果有需要的話)。在調(diào)用方法時(shí),我們無(wú)需明確提供與參數(shù)self相對(duì)應(yīng)的參數(shù)。 通常,我們需要定義的一個(gè)最重要的方法是.__init__()。在類的實(shí)例創(chuàng)建后就會(huì)調(diào)用這個(gè)方法。該方法負(fù)責(zé)初始化類成員。我們定義的.__init__()如下:
下面,我們來(lái)創(chuàng)建一個(gè)MyClass實(shí)例,看看這個(gè)初始化方法的具體工作。我們的.__init__()方法需要三個(gè)參數(shù)(arg_1、arg_2和arg_3),記住我們不需要傳遞與self對(duì)應(yīng)的第一個(gè)參數(shù)。所以,在實(shí)例化對(duì)象時(shí),我們需要傳遞三個(gè)參數(shù):
上述聲明產(chǎn)生的結(jié)果如下:
現(xiàn)在我們得到了一個(gè)類,它有一個(gè)方法.__init__(),以及這個(gè)類的一個(gè)實(shí)例。 數(shù)據(jù)屬性 下面我們來(lái)修改MyClass,增加一些數(shù)據(jù)屬性。 我們利用.__init__()初始化和定義了實(shí)例,我們還可以在這個(gè)方法或其他實(shí)例方法中,通過(guò)給某個(gè)數(shù)據(jù)屬性賦值的方式改變屬性值:
現(xiàn)在MyClass有三個(gè)數(shù)據(jù)屬性:
我們可以利用Python的解包機(jī)制,用更緊湊的形式編寫這段代碼:
屬性名稱中的下劃線(_)是為了表明這些屬性是“私有”屬性:
Python對(duì)象的數(shù)據(jù)屬性通常存儲(chǔ)在名為.__ dict__的字典中,它也是對(duì)象的屬性之一。但是,你也可以將數(shù)據(jù)屬性存儲(chǔ)在其他地方。我們可以直接訪問(wèn)__dict__,或利用Python的內(nèi)置函數(shù)vars()獲取.__ dict__:
名字修飾過(guò)程把鍵'__z'變成了'_MyClass__z'。 我們可以把.__ dict__當(dāng)成普通的Python字典使用。 獲取和修改與數(shù)據(jù)屬性關(guān)聯(lián)的值的常規(guī)方法如下:
請(qǐng)注意,我們無(wú)法訪問(wèn).__ z,因?yàn)?__ dict__沒(méi)有鍵'__z'。 實(shí)例方法 下面,我們來(lái)創(chuàng)建兩個(gè)實(shí)例方法: ●.set_z():修改.__ z。 ●.get_z():返回.__ z的值。 請(qǐng)記住,每個(gè)實(shí)例方法的第一個(gè)參數(shù)(按照約定名為self)引用對(duì)象本身,但我們無(wú)需在調(diào)用方法時(shí)指定這個(gè)參數(shù):
方法.get_z()和.set_z()提供了傳統(tǒng)的檢索和修改.__ z值的方法:
你也可以在.get_z()和.set_z()中添加其他功能,例如檢查數(shù)據(jù)的有效性。這種方法實(shí)現(xiàn)了面向?qū)ο缶幊讨械囊粋€(gè)主要概念:封裝。 屬性 還有一種方法(一種更Python的方式)訪問(wèn)和修改數(shù)據(jù)屬性是使用屬性。屬性封裝了一系列方法:getter、setter和deleter,但其行為與普通的數(shù)據(jù)屬性相同。 下面的代碼實(shí)現(xiàn)了屬性.z,其中還包含.get_z()和.set_z()的功能:
如下,我們利用相應(yīng)的屬性.z來(lái)訪問(wèn)和修改數(shù)據(jù)屬性.__ z:
這段代碼比上述示例更精簡(jiǎn)優(yōu)雅。 類與靜態(tài)方法 除了實(shí)例方法和屬性之外,類還可以擁有類方法和靜態(tài)方法。 下面讓我們?yōu)镸yClass添加三個(gè)方法:
方法.f()是一個(gè)實(shí)例方法。實(shí)例方法的第一個(gè)參數(shù)是對(duì)象本身的引用。這些方法可以利用self訪問(wèn)對(duì)象,利用vars(self)或self.__dict__訪問(wèn)對(duì)象的數(shù)據(jù)屬性,還可以利用type(self)或self.__class__訪問(wèn)對(duì)象對(duì)應(yīng)的類,而且它們還可以擁有自己的參數(shù)。 方法.g()的開頭包含修飾器@classmethod,表明這是一個(gè)類方法。每個(gè)類方法的第一個(gè)參數(shù)都會(huì)指向類本身,按照約定該參數(shù)名為cls。與實(shí)例方法的情況一樣,我們不需要明確提供與cls對(duì)應(yīng)的參數(shù)。而類方法可以利用cls和自己的參數(shù)訪問(wèn)類本身。 方法.h()的開頭包含修飾器@staticmethod,表明這是一個(gè)靜態(tài)方法。靜態(tài)方法只能訪問(wèn)自己的參數(shù)。 Python中常見的調(diào)用實(shí)例方法的方法如下:
通常,我們應(yīng)該直接通過(guò)類(而不是實(shí)例)調(diào)用類方法和靜態(tài)方法:
請(qǐng)記住,我們不需要傳遞類方法的第一個(gè)參數(shù):與cls相對(duì)應(yīng)的參數(shù)。 但是,我們可以像下面這樣調(diào)用類方法和靜態(tài)方法:
當(dāng)我們調(diào)用c.g或c.h,但實(shí)例成員沒(méi)有這樣的名稱時(shí),Python會(huì)搜索類和靜態(tài)成員。 繼承是面向?qū)ο缶幊痰牧硪粋€(gè)重要特性。在這個(gè)概念中,類(稱為子類或派生類)會(huì)繼承其他類(稱為超類或基類)的數(shù)據(jù)和函數(shù)成員。 在Python中,所有類都會(huì)默認(rèn)繼承Python自帶的類對(duì)象。但是,我們可以根據(jù)需要定義合適的類繼承層次結(jié)構(gòu)。 例如,我們可以創(chuàng)建一個(gè)名為MyOtherClass的新類,該類繼承了MyClass:
如上,MyOtherClass擁有MyClass的成員:.x、._y、.__z以及.f()。你可以通過(guò)語(yǔ)句super().__init__(x, y, z)初始化基類的數(shù)據(jù)成員x、._y和.__z,該語(yǔ)句會(huì)調(diào)用基類的.__init__()方法。 除此之外,MyOtherClass還有自己的成員:.__u、.__v、.__w和.f_()。 下面,我們通過(guò)vars()獲取數(shù)據(jù)成員:
我們可以調(diào)用基類和派生類中的所有方法:
但是,如果派生類包含的某個(gè)成員與基類同名,則優(yōu)先使用派生類的成員。 面向?qū)ο缶幊淌荘ython支持的編程范式之一。面向?qū)ο筇N(yùn)含的抽象以及表征的現(xiàn)實(shí)世界行為在某些時(shí)候會(huì)非常有幫助性。然而,有時(shí)也可能會(huì)違反直覺(jué),并為開發(fā)過(guò)程帶來(lái)不必要的麻煩。 在本文中,我們介紹了如何利用Python編寫基本的面向?qū)ο蟪绦?。Python中還有很多類和面向?qū)ο蟮墓δ埽纾?/span>
等等…… 現(xiàn)如今面向?qū)ο笫欠浅A餍械木幊谭绞?。如果你立志做一名Python開發(fā)人員,那么就應(yīng)該學(xué)習(xí)面向?qū)ο缶幊獭5?qǐng)不要忘記,Python還支持其他編程范式,例如過(guò)程式編程、函數(shù)式編程等,在某些情況下也許選用這些范例更為合適。 盡情享受編程的快樂(lè)! |
|
|
來(lái)自: 風(fēng)聲之家 > 《python》