python 中一切皆對象。
先說 說面向對象語言三大特性:封裝、繼承、多態。
1、封裝分兩個層面
第一層面:創建類和對象時,分別創建兩人者的名稱空間,只能通過類名加"."或者obj.的方式訪問里面的屬性方法;
第二層面:類中可以把某些屬性或方法隱藏起來,或者定義為私有,只在類內部使用,在類的外面無法訪問,或者只留下少量的接口(函數)供外部訪問。
2、繼承
python中可以多繼承,其繼承順序使用了C3算法,可以通過 類.__mro__ 來查看
mro: method resolution order (方法解釋順序)
1 class A(object): 2 def say(self): 3 print('AA say') 4 5 class B(object): 6 def say(self): 7 print('BB say') 8 9 class C(A): 10 def say(self): 11 print('CC say') 12 13 class D(B): 14 def say(self): 15 print('DD say') 16 17 class E(D, C): 18 def say(self): 19 print('EE say') 20 21 22 d = E() 23 print(E.__mro__) 24 d.say()
輸出如下:
(<class '__main__.E'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) EE say
這里只是展示怎么查看多繼承的查找順序,關於繼承的復雜結構還有很多,這里就不一一列了,結構不一樣,繼承的順序也不一樣,有的廣度優先有的深度優先,自己試吧。
繼承的順序算法比較復雜,強烈不推薦使用這種多繼承的方式,要不然會很混亂。推薦使用Mixin的多繼承方式,即所繼承的每個類中只實現了同一種方法,不存在多方覆蓋的問題。不過若是真的設計成了多繼承的復雜結構,調試代碼時還是盡量使用mro來查看一下到底執行了哪個父類中的屬性方法。
3、多態
python不支持多態,或者說python本來就是多態語言。
鴨子類型:
Duck typing 這個概念來源於美國印第安納州的詩人詹姆斯·惠特科姆·萊利(James Whitcomb Riley,1849-
1916)的詩句:”When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”
上代碼,來源於網上很經典的案例:
class Duck(): def walk(self): print("I walk like a duck") def swim(self): print('I swim like a duck') class Person(): def walk(self): print("I walk like a duck") def swim(self): print('I swim like a duck')
可以看出Pseron類擁有和Duck類一樣的方法,當程序調用Duck類,並利用了其中的walk和swim方法時,我們傳入Person類也一樣可以運行,程序並不會檢查類型是不是Duck,只要他擁有 walk()和swim()方法,就能被正確地調用。
舉例:
一個對象實現了__getitem__魔法方法,那python解釋器就會把它當做一個callection,你就可以對這個對象進行切片、獲取子項等; 如果一個對象實現了__iter__和next方法,python就會把它當成一個iterator, 你就可以對這個對象通過循環獲取各個子項; 如果一個對象中實現了__len__方法,你就可以對這個對象執行len()對它進行計數。
結論:
面向對象是很強大的,在python編程之初我們要強制自己不要什么都用函數來實現,要多寫類,即使是很小的功能實現也用類來做,養成習慣,久了以后關於類和對象的相關知識自然接觸的就多,也能寫出更加復雜的程序。
