簡述 Python 的類和物件
系列最後一篇來說說Python中的類與物件,Python這門語言是無處不物件,如果你曾淺要了解過Python,你應該聽過Python是一種面向物件程式設計的語言,所以你經常可能會看到面向“物件”程式設計這類段子,而面向物件程式設計的語言都會有三大特徵:封裝、繼承、多型。
我們平時接觸到的很多函式、方法的操作都具有這些性質,我們只是會用,但還沒有去深入瞭解它的本質,下面就介紹一下關於類和物件的相關知識。
封裝
封裝這個概念應該並不陌生,比如我們把一些資料封裝成一個列表,這就屬於資料封裝,我們也可以將一些程式碼語句封裝成一個函式方便呼叫,這就是程式碼的封裝,我們也可以將資料和程式碼封裝在一起。用術語表示的話,就是可以將屬性和方法進行封裝,從而得到物件。
首先我們可以定義一個類,這個類中有屬性和方法,但有的夥伴會比較好奇,屬性和方法不是會封裝成物件嘛,為什麼又變成類了?舉個例子,類就好比是一個毛坯房,而物件是在毛坯房的基礎上改造成的精裝房。
class XiaoMing: #屬性 height = 180 weight = 65 sex = '男' #方法 def run(self): print('小明在跑步') def sleep(self): print('小明在睡覺')
在類定義完成時就建立了一個類物件,它是對類定義建立的名稱空間進行了一個包裝。類物件支援兩種操作:屬性引用和例項化。
屬性引用的語法就是一般的標準語法:obj.name。比如XiaoMing.height和XiaoMing.run就是屬性引用,前者會返回一條資料,而後者會返回一個方法物件。
In[1]:print(XiaoMing.height) Out[1]:180 In[2]:print(XiaoMing.run) Out[2]:<function XiaoMing.run at 0x0000021C6239D0D0>
這裡也支援對類屬性進行賦值操作,比如為類中的weight屬性賦予一個新值。
In[3]:print(XiaoMing.weight) Out[3]:65 In[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 = x self.y = y def 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、issubclass(class,classinfo)
判斷一個類是否是另一個類的子類,如果是則返回True,反之則返回False。
class Parent: pass class Child(Parent): pass print(issubclass(Child,Parent)) ''' True '''
需要注意的有兩點:
- 1.第二個引數不僅可以傳入類,也可以傳入由類組成的元組。
- 2.一個類被判定為自身的子類,也就是說這兩個引數傳入同一個類時,也會返回True。
print(issubclass(Parent,Parent)) ''' 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。
以上就是簡述 Python 的類和物件的詳細內容,更多關於Python 的類和物件的資料請關注我們其它相關文章!