前言:java
與第一篇的面向對象內容不一樣的是,第一篇中的面向對象更多的是與類、對象結合起來的概念粗淺理解,就是在編程歷史中誕生的一種思想方法。python
這篇的面向對象編程,更多落實到在語言設計實現中,是如何體現面向對象這一設計思想的。c++
本篇內容圍繞 python基礎教程這段:
在面向對象編程中,術語對象大體意味着一系列數據(屬性)以及一套訪問和操做這些數據的方法。使用對象而非全局變量和函數的緣由有多個,下面列出了使用對象的最重要的好處。
多態:可對不一樣類型的對象執行相同的操做,而這些操做就像「被施了魔法」同樣可以正常運行。
封裝:對外部隱藏有關對象工做原理的細節。
繼承:可基於通用類建立出專用類。
內容較多,這篇爲上篇。
Content:django
- 類和對象的多態
編程
- - 多態和鴨子類型編程語言
1.什麼是多態?函數
2.什麼是鴨子類型?測試
3.動態python的多態和其餘動態語言的區別? 和靜態語言多態的區別?spa
4.python語言中鴨子類型的應用?設計
(
下篇內容:
- 類和對象的封裝、繼承
- - 抽象基類
- - 類屬性,實例屬性和其查找順序
- - 靜態方法、類方法、對象方法
- - 數據封裝和私有屬性
- - python的自省機制
- - python中的super函數
- - django中的繼承
- - 上下文管理器
)
一 類的多態和鴨子類型
1.什麼是多態?
同一操做做用於不一樣的對象,能夠有不一樣的解釋,產生不一樣的執行結果,這就是多態性。
簡單來講,就是有一個父類,不少子類繼承了父類的方法可是對父類的方法進行了本身的定製(或者是在python中不少不一樣的類實現了同一個名字的方法),我生成這些子類的全部對象都有同一個方法,調用這些對象的相同方法可是有不一樣的結果。
多態的好處:
a.應用程序沒必要爲每個派生類編寫功能調用,只須要對抽象基類進行處理便可。大大提升程序的可複用性。//繼承
b.派生類的功能能夠被基類的方法或引用變量所調用,這叫向後兼容,能夠提升可擴充性和可維護性。 //多態的真正做用
2.什麼是鴨子類型?
即全部的類都實現了同一種方法,調用得時候能夠同時調用這一種方法。在任何對象中,指定某一個方法名,全部類均可以通用,就爲鴨子類型。(是否是很像多態的概念?)
鴨子類型(英語:duck typing)是動態類型的一種風格。在這種風格中,一個對象有效的語義,不是由繼承自特定的類或實現特定的接口,而是由當前方法和屬性的集合決定。這個概念的名字來源於由James Whitcomb Riley提出的鴨子測試,「鴨子測試」能夠這樣表述:「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就能夠被稱爲鴨子。」
python是很崇尚鴨子類型的。
3. python的鴨子類型和多態是什麼關係呢?和其餘靜態語言多態的區別?
多態是一個普遍的概念,全部面向對象編程語言中,都具備多態性,可是咱們不說python支持多態,只說c++,java支持多態。由於python自己就是多態的,而且python不存在很少態。
什麼意思呢?
就是傳統c++,java所說的多態,是全部子類,繼承了父類的全部方法狀況下,定義了本身的方法,不一樣對象(繼承了同一父類的類生成的)調用了同一方法執行不一樣。這叫咱們實現了這二者語言中的多態。
可是python所崇尚的鴨子類型更牛批的地方在於,我不在意是否是有父類、父類是誰,任何多個沒有繼承的類,我只要實現了相同名字的方法,那麼這幾個不一樣類生成的對象就有了同一個特性,能用同一個方法,就能有多態性。
Python是隻要你有如出一轍的函數存在,那麼他就能夠按照多態的處理方式來給你處理。
例子:
若是用python來表示c++、java中的多態:
class Animals():
def say(self):
print("say something")
class Duck(Animals):
def say(self):
print("gaga")
class Dog(Animals):
def say(self):
print("wangwang")
class Miao(Animals):
def say(self):
print("miaomiao")
pythonic的多態:
class Cat():
def say(self):
print("喵")
class Dog():
def say(self):
print("汪")
class Duck():
def say(self):
print("gaga")
animals_list=[Cat,Dog,Duck]
for i in animals_list:
i().say()
一般不提倡繼承式的多態,更提倡第二種pythonic的多態。
是否是很奇怪,看起來第一種繼承式的更經常使用更有用的樣子?注意不要混淆python繼承的經常使用狀況和多態的經常使用狀況。看4中python的實際應用大概就能明白了。
4.鴨子類型在python語言設計中的實際應用?
例用list實現了的extend方法來看。
描述:extend() 函數用於在列表末尾一次性追加另外一個序列中的多個值(用新列表擴展原來的列表)。
語法:extend()方法語法:list.extend(seq)
extend方法的參數是接收一個可迭代的對象,而list、tuple、和set對象都實現了__iter__(self)(定義當迭代容器中的元素的行爲),這就是所謂的,
它不關注對象的類型,而是關注對象具備的行爲(方法)。
這個接口的描述告訴咱們,不是隻用list做爲參數,而是隻要是
可迭代對象均可以。甚至是迭代類型的生成器也是能夠的。
本身實現一個類,是能夠迭代的,也是能夠放進來的。
這點是很重要的,可迭代類型共同具備的方法__iter__,來給全部的類定義了一種性質,就是它可迭代,就跟3中全部的類都實現了say這個方法,那麼它們均可以say同樣。這就是鴨子類型的真正用處,重點關注list、dict、set都由於__iter__成爲了可迭代類型,而不是它是list類型、set類型等。(這裏與以前的魔法函數又對上啦)
ps.調用對象裏的 __getitem__、__iter__等魔法函數,就說明這個對象是可迭代的,這個方法不會拋異常,而會一直執行下去。
關於魔法函數和鴨子類型的總結:
a.經過魔法函數對python對象進行了分組,對同組對象進行相同行爲的定義實現多態。
b.鴨子類型在python最初設定的時候就設定好了,對於一個對象,咱們重點在於其設置的方法,而不是對象類型。