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