【Python】Python的类和对象(长文系列第⑤篇)
系列最后一篇來說說Python中的類與對象,Python這門語言是無處不對象,如果你曾淺要了解過Python,你應該聽過Python是一種面向對象編程的語言,所以你經常可能會看到面向“對象”編程這類段子,而面向對象編程的語言都會有三大特征:封裝、繼承、多態。
我們平時接觸到的很多函數、方法的操作都具有這些性質,我們只是會用,但還沒有去深入了解它的本質,下面就介紹一下關于類和對象的相關知識。
封裝
封裝這個概念應該并不陌生,比如我們把一些數據封裝成一個列表,這就屬于數據封裝,我們也可以將一些代碼語句封裝成一個函數方便調用,這就是代碼的封裝,我們也可以將數據和代碼封裝在一起。用術語表示的話,就是可以將屬性和方法進行封裝,從而得到對象。
首先我們可以定義一個類,這個類中有屬性和方法,但有的伙伴會比較好奇,屬性和方法不是會封裝成對象嘛,為什么又變成類了?舉個例子,類就好比是一個毛坯房,而對象是在毛坯房的基礎上改造成的精裝房。
class?XiaoMing:#屬性height?=?180weight?=?65sex?=?'男'#方法def?run(self):print('小明在跑步')def?sleep(self):print('小明在睡覺')在類定義完成時就創建了一個類對象,它是對類定義創建的命名空間進行了一個包裝。類對象支持兩種操作:屬性引用和實例化。
屬性引用的語法就是一般的標準語法:obj.name。比如XiaoMing.height和XiaoMing.run就是屬性引用,前者會返回一條數據,而后者會返回一個方法對象。
In[1]:print(XiaoMing.height) Out[1]:180In[2]:print(XiaoMing.run) Out[2]:<function?XiaoMing.run?at?0x0000021C6239D0D0>這里也支持對類屬性進行賦值操作,比如為類中的weight屬性賦予一個新值。
In[3]:print(XiaoMing.weight) Out[3]:65In[4]:XiaoMing.weight?=?100 In[5]:print(XiaoMing.weight) Out[5]:100而類的實例化可以將類對象看作成一個無參函數的賦值給一個局部變量,如下:
In[6]:ming?=?XiaoMing()ming就是由類對象實例化后創建的一個實例對象,通過實例對象也可以調用類中的屬性和方法。
In[7]:ming.run() Out[7]:小明在跑步In[8]:print(xiaoming.height) Out[8]:180 #通過向類對象調用方法返回的方法對象中傳入實例對象也可以達到同樣效果 In[11]:XiaoMing.run(ming) Out[11]:小明在跑步魔法方法__init__
類在實例化過程中并不都是像上面例子一樣簡單的,一般類都會傾向將實例對象創建為有初始狀態的,所以在類中可能會定義一個__init__的魔法方法,這個方法就可以幫助接收、傳入參數。
而一個類如果定義了__init__方法,那么在類對象實例化的過程中就會自動為新創建的實例化對象調用__init__方法,請看下面這個例子。
class?Coordinates:def?__init__(self,x,y):self.x?=?xself.y?=?ydef?print_coor(self):print('當前坐標為(%s,%s)'%(self.x,self.y))可以看到在__init__()中傳入了參數x和y,然后在print_coor中需要接收參數x和y,接下來通過實例化這個類對象,驗證一下參數是否能通過__init__()傳遞到類的實例化操作中。
In[9]:coor?=?Coordinates(5,3) In[10]:coor.print_coor()Out[10]:當前坐標為(5,3)繼承
所謂繼承就是一個新類在另一個類的基礎上構建而成,這個新類被稱作子類或者派生類,而另一個類被稱作父類、基類或者超類,而子類會繼承父類中已有的一些屬性和方法。
class?Mylist(list):pass list_?=?Mylist() list_.append(1) print(list_) ''' [1] '''比如上面這個例子,我并沒有將list_定義成一個列表,但它卻能調用append方法。原因是類Mylist繼承于list這個基類,而list_又是Mylist的一個實例化對象,所以list_也會擁有父類list擁有的方法。
當然可以通過自定義類的形式實現兩個類之間的繼承關系,我們定義Parent和Child兩個類,Child中沒有任何屬性和方法,只是繼承于父類Parent。
class?Parent:def?par(self):print('父類方法') class?Child(Parent):pass child?=?Child() child.par() ''' 父類方法 '''覆蓋
當子類中定義了與父類中同名的方法或者屬性,則會自動覆蓋父類對應的方法或屬性,還是用上面這個例子實現一下,方便理解。
class?Parent:def?par(self):print('父類方法') class?Child(Parent):def?par(self):print('子類方法') child?=?Child() child.par() ''' 子類方法 '''可以看到子類Child中多了一個和父類Parent同名的方法,再實例化子類并調用這個方法時,最后調用的是子類中的方法。
Python中繼承也允許多重繼承,也就是說一個子類可以繼承多個父類中的屬性和方法,但是這類操作會導致代碼混亂,所以大多數情況下不推薦使用,這里就不過多介紹了。
多態
多態比較簡單,比如定義兩個類,這兩個類沒有任何關系,只是兩個類中有同名的方法,而當兩個類的實例對象分別調用這個方法時,不同類的實例對象調用的方法也是不同的。
class?XiaoMing:def?introduce(self):print("我是小明") class?XiaoHong:def?introduce(self):print("我是小紅")上面這兩個類中都有introduce方法,我們可以實例化一下兩個類,利用實例對象調用這個方法實現一下多態。
In[12]:ming?=?XiaoMing() In[13]:hong?=?XiaoHong()In[14]:ming.introduce() Out[14]:我是小明In[15]:hong.introduce() Out[15]:我是小紅常用BIF
1、isssubclass(class,classinfo)
判斷一個類是否是另一個類的子類,如果是則返回True,反之則返回False。
class?Parent:pass class?Child(Parent):pass print(issubclass(Child,Parent)) ''' True '''需要注意的有兩點:
1.第二個參數不僅可以傳入類,也可以傳入由類組成的元組。
2.一個類被判定為自身的子類,也就是說這兩個參數傳入同一個類時,也會返回True。
2、isinstance(object,classinfo)
判斷一個對象是否為一個類的實例對象,如果是則返回True,反之則返回False。
class?Parent:pass class?Child:pass p?=?Parent() c?=?Child() print(isinstance(p,Parent,Child)) #True print(isinstance(c,Parent)) #False需要注意的有兩點:
1.第二個參數不僅可以傳入類,也可以傳入由類組成的元組。
2.如果第一個參數傳入的不是一個對象,則總是返回False。
3、hasattr(object,name)
判斷一個實例對象中是否包含一個屬性,如果是則返回True,反之則返回False。
class?Parent:height?=?100 p?=?Parent() print(hasattr(p,'height')) ''' True '''需要注意的是第二個參數name必須為字符串形式傳入,如果不是則會返回False。
往期精彩回顧適合初學者入門人工智能的路線及資料下載(圖文+視頻)機器學習入門系列下載中國大學慕課《機器學習》(黃海廣主講)機器學習及深度學習筆記等資料打印《統計學習方法》的代碼復現專輯 AI基礎下載機器學習交流qq群955171419,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【Python】Python的类和对象(长文系列第⑤篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的世界服务器修改末地难度,涨姿势啦!我
- 下一篇: java null和 的区别_java中