深圳商城網(wǎng)站建設(shè)報(bào)價(jià)沈陽(yáng)seo按天計(jì)費(fèi)
? ? ? ? python是一種面向?qū)ο蟮淖兂烧Z(yǔ)言。
? ? ? ? python幾乎所有的東西都是對(duì)象,包括對(duì)象和屬性。
一.類的定義
? ? ? ? python類的定義:
class ClassName:pass:
? ? ? ? 實(shí)例:
注意:? ? ? ??
- ?類中的函數(shù)稱為方法,有關(guān)于函數(shù)的一切適用于方法,唯一的區(qū)別在于函數(shù)的調(diào)用方式。
- 方法__init__()是一個(gè)特殊的方法,每當(dāng)你根據(jù)類進(jìn)行實(shí)例化時(shí)(創(chuàng)建對(duì)象),Python都會(huì)自動(dòng)調(diào)用,方法名是一種約定,旨在避免與普通方法發(fā)生沖突。相當(dāng)于C++中的構(gòu)造函數(shù)。
- 當(dāng)使用類實(shí)例化的對(duì)象,調(diào)用類中的方法時(shí),Python會(huì)自動(dòng)將實(shí)例化的對(duì)象傳入,類中的方法必須用一個(gè)變量接收,如實(shí)例中的self變量(變量名可以隨便取)。使用該變量調(diào)用實(shí)例中的方法和屬性。
- 類的組成包括:類的屬性,實(shí)例方法,靜態(tài)方法,類方法。類名在python中也是對(duì)象,是一個(gè)沒(méi)有實(shí)例(實(shí)例屬性和方法)的對(duì)象。
類的屬性:分為實(shí)例屬性和類屬性。
????????實(shí)例屬性是指在實(shí)例化一個(gè)類時(shí)動(dòng)態(tài)添加到實(shí)例對(duì)象中的變量,可以通過(guò)實(shí)例化對(duì)象訪問(wèn)。
????????類屬性是指被類的所有實(shí)例化對(duì)象,包括類名本身對(duì)象共享的變量,可以通過(guò)類名或類的實(shí)例化對(duì)象訪問(wèn)。類屬性就是靜態(tài)屬性。
?實(shí)例方法,靜態(tài)方法和類方法:python實(shí)例方法,類方法和靜態(tài)方法區(qū)別_兩片空白的博客-CSDN博客
二.類實(shí)例化對(duì)象
- 對(duì)象創(chuàng)建和屬性方法的使用
實(shí)例對(duì)象=類名()
使用通過(guò)'.'點(diǎn)操作符來(lái)訪問(wèn)屬性和方法。
- 實(shí)例方法的調(diào)用有兩種方式:
實(shí)例對(duì)象.方法(...)
類名.方法(實(shí)例對(duì)象, ...)
my_dog=Dog("tager", 10) Dog.sit(my_dog)
- 對(duì)象的打印__str__()方法
? ? ? ? 當(dāng)我們實(shí)例化一個(gè)類對(duì)象,使用print打印類對(duì)象時(shí),得到的時(shí)對(duì)象的地址。沒(méi)有得到對(duì)象的屬性。
? ? ? ? ?可以在類中定義__str__()方法,print時(shí)會(huì)調(diào)用__str__()方法,__str__()方法中需要返回字符串類型。
三.封裝
? ? ? ? 封裝的作用:一是可將屬性和行為包裝到類對(duì)象中,需要通過(guò)實(shí)例化對(duì)象或類名來(lái)訪問(wèn)。二是在變量或者函數(shù)名前加兩個(gè)"_",使屬性和方法實(shí)現(xiàn)私有化。只能在類中訪問(wèn),不能在類外訪問(wèn)。
? ? ? ? python中實(shí)現(xiàn)私有化的方法比較的方法比較簡(jiǎn)單,即在準(zhǔn)備實(shí)現(xiàn)私有化的方法和屬性名字前面加兩個(gè)下劃線即可。類中所有雙下劃線的名稱都會(huì)自動(dòng)變成:_類名__數(shù)據(jù)名的形式。比如:__x,python會(huì)自動(dòng)將其變形成:_類名__x。
? ? ? ? ?由于python將__x轉(zhuǎn)化成了_類名__x,于是會(huì)有下面的情況:
? ? ? ? 以_類名__x的形式可以訪問(wèn)到python的私有變量,這種情況是需要程序員來(lái)避免的。
四.繼承
? ? ? ? 在python中,一個(gè)類可以繼承另外一個(gè)類。原有的類稱為父類,而新的類稱為子類。子類繼承父類的所有屬性和方法,同時(shí)還可以定義自己的屬性和方法。
? ? ? ? 沒(méi)有在括號(hào)中填父類,默認(rèn)繼承object類。
? ? ? ? 繼承的作用可以實(shí)現(xiàn)代碼的復(fù)用。
語(yǔ)法:
class 子類類名(父類1, 父類2...):pass
? ? ? ? 4.1 子類的__init()__方法
? ? ? ? 創(chuàng)建子類實(shí)例時(shí),python首先需要完成的任務(wù)是給父類的所有屬性賦值。在子類__init()__中實(shí)現(xiàn)。
? ? ? ? 在實(shí)例化子類對(duì)象時(shí),需要將子類和父類的成員都傳入。
? ? ? ? 4.2 方法和屬性重寫(xiě)
- 屬性重寫(xiě)
- 方法重寫(xiě)
? ? ? ? 子類繼承父類方法,當(dāng)父類方法不符合子類行為時(shí),可以對(duì)父類的方法進(jìn)行重寫(xiě)。重寫(xiě)的條件在于,需要子類的重寫(xiě)的方法和父類方法同名(只需要方法名相同即可,參數(shù)不需要相同)。
? ? ? ? 4.3 繼承原理(MRO——方法搜索順序)
- 主要用于繼承中方法和屬性的調(diào)用順序,這個(gè)MRO列表就是一個(gè)簡(jiǎn)單的所有基類的線性順序列表。
- python中針對(duì)類提供了一個(gè)內(nèi)置屬性__mro__可以查看搜索順序,搜索方法和屬性時(shí)按照MRO列表順序來(lái)進(jìn)行搜索的。
- 而這個(gè)MRO列表的構(gòu)造是通過(guò)一個(gè)C3線性化算法來(lái)實(shí)現(xiàn)的。
搜索方法和屬性規(guī)則:?
- 如果在當(dāng)前類中找到方法直接執(zhí)行,不再搜索。
- 如果當(dāng)前類中沒(méi)有找到方法,玩后面的順序找,找到后執(zhí)行,不在搜索。
- 如果在整個(gè)搜索順序中都沒(méi)有找到,程序報(bào)錯(cuò)。?
- 使用super來(lái)查找和直接查找屬性和方法都是這個(gè)規(guī)則。
????????python的繼承不像C++中的繼承,會(huì)在派生類中繼承成員變量,實(shí)例化對(duì)象時(shí),也會(huì)創(chuàng)建基類的成員變量。這樣會(huì)導(dǎo)致在菱形繼承時(shí),會(huì)出現(xiàn)變量的冗余和二義性。
????????而python中的繼承通過(guò)MRO機(jī)制避免了這個(gè)問(wèn)題,按照列表順序在基類中查找方法或者屬性,而不是在子類中創(chuàng)建父類變量。
重寫(xiě)原理:
? ? ? ? 按照mro順序列表查找方法和屬性時(shí),當(dāng)子類重寫(xiě)了方法或者屬性,調(diào)用方法或者屬性時(shí),在子類中找到方法(與參數(shù)無(wú)關(guān))和屬性,不會(huì)繼續(xù)搜索。?基類的方法和屬性等價(jià)于被隱藏了。
????????4.3?super()用法
? ? ? ? 4.2.1 定義
????????super()是python中調(diào)用父類(超類)的一種方法。在子類中可以通過(guò)super()方法調(diào)用父類的方法和屬性。超類是指具有兩層以上繼承關(guān)系的類。
? ? ? ? 4.2.2 作用
- 在繼承中讓代碼維護(hù)更加簡(jiǎn)單。
- 解決菱形繼承帶來(lái)重復(fù)調(diào)用,查找順序(MRO)問(wèn)題。
? ? ? ? 4.2.3 使用——通過(guò)super()來(lái)調(diào)用子類和父類同名的方法
- 單繼承
? ? ? ? super().add(num)確實(shí)調(diào)用了父類的add()方法,并且父類中的實(shí)例和子類中的實(shí)例地址相同,說(shuō)明是一個(gè)實(shí)例self。在父類中的self.n實(shí)際是子類的n,所以算出來(lái)n的結(jié)果是7。
- 多繼承
?五.多態(tài)
? ? ? ? 多態(tài)是在繼承體系中,調(diào)用相同的方法,通過(guò)傳入不同的對(duì)象,有不同的動(dòng)作。
? ? ? ? python中的多態(tài)沒(méi)有C++中這么復(fù)雜,由于python中的變量無(wú)序聲明數(shù)據(jù)類型就可以賦值,python對(duì)變量賦值就是創(chuàng)建一個(gè)新的變量,這個(gè)變量就是對(duì)應(yīng)的類型。
? ? ? ? python中的多態(tài)是通過(guò)子類繼承父類,子類重寫(xiě)父類的方法。在當(dāng)使用該方法時(shí),會(huì)根據(jù)變量的不同來(lái)調(diào)用不同的方法。
- 非繼承和多態(tài),不同類中有相同方法。
? ? ? ? 由于沒(méi)有繼承關(guān)系,所以不屬于多態(tài)。
- ?多態(tài),重寫(xiě)父類方法
?六.特殊屬性和方法
? ? ? ? 6.1 特殊屬性
- __dict__
? ? ? ? 放回類中方法或?qū)傩缘淖值?/p>
- __class__
- __bases和__base__:使用類調(diào)用
__base__:輸出第一個(gè)父類類型。
__bases__:輸出父類類型的元組。元組每一個(gè)位置都是一個(gè)類類型,都可以定義變量。
- __mro__
????????輸出繼承了那些父類類型的元組,查找屬性和方法的順序表。
? ? ? ? 6.2 特殊方法?
- __subclasses__()
? ? ? ? 輸出子類列表。
- ?__add__():重載+操作符
類不支持'+'操作,支持需要實(shí)現(xiàn)__add__()方法。
- ?__len__()內(nèi)置方法計(jì)算長(zhǎng)度
? ? ? ? len()函數(shù)中會(huì)調(diào)用類的__len__()方法
- ?__new__()在創(chuàng)建對(duì)象時(shí)調(diào)用,__init__()在初始化對(duì)象時(shí)調(diào)用
? ? ? ? 想看下圖發(fā)現(xiàn):
? ? ? ? 實(shí)例化對(duì)象時(shí),先調(diào)用的__new__方法,再調(diào)用__init__方法。
????????cls地址和A類對(duì)象地址相同。新創(chuàng)建的對(duì)象的obj和a和__init__方法中的self相同。
? ? ? ? 即,
- 在調(diào)用A的__new__時(shí)A對(duì)象地址賦值給了cls
- cls傳給super().__new__方法,新建完的對(duì)象傳給obj
- 調(diào)用完A的__new__后調(diào)用__init__,obj對(duì)象傳給了self
- self初始化后賦值給了a。
?