在搞清了各類數據類型、賦值判斷、循環之後若是是從C++、Java語言入手的,就會有一個深坑要過:OOP(object oriented programming):公私有保護、多重繼承、多態派生、純函數、抽象類、友元函數等等等等一堆專有名詞等着你呢!還好還好!Python是一門相對友好一點的語言,他在創立之初就鼓勵命令交互式的輕量級編程。理論上,Python的命令式語言是圖靈完備的,也就是說命令式語言,理論上能夠左到任何其餘任何語言能作到的全部事情,甚至進一步,僅僅以靠彙編語言的MOV指令,就能實現圖靈完備編程。html
那爲何咱們不這麼作呢?事實上「上古時代」的程序員就是這麼作的,可隨着程序功能性複雜的逐步提高,需求的不斷迭代,不少老舊的代碼修改起來就無比麻煩,根本沒法迭代和維護,甚至只能重構。這也就是爲何古老的代碼稱爲「屎山」的緣由。程序員
傳統的命令式語言有無數重複性的代碼,雖然函數的誕生減小了不少重複的代碼。但隨着計算機的發展,只有函數是不夠的,要把更加抽象的概念引入計算機才能緩解(注意是緩解而不是解決),這樣OOP就應運而生。編程
一.基礎概念ide
面向對象的基礎概念在Python篇面向對象編程和Python面向對象進階使用總結過,這裏就再也不多說了,總之就是這四個點,雖然總結的互式很嚴謹,但也能夠直觀的瞭解一下:函數
1.類:一羣有着類似性的事物的集合,在Python裏對應的是class;單元測試
2.對象:集合中的一個失誤,Python裏對應由class生成的某一個object;測試
3.屬性:對象的某個靜態特徵;idea
4.函數:對象的某個動態能力。spa
二.幾種很是規:類函數、靜態函數等設計
有幾種函數咱們再鞏固一下:
class Peaple(): NATIONALITY = 'China' #常量/類變量 def __init__(self,name,sex,age,salary=1000): #構造函數 self.name = name self.sex = sex self.age = age self.__salary = salary #私有屬性 @classmethod #類方法,不能調用實例屬性,只能調用類變量 def fun(self): print(self.NATIONALITY) @staticmethod #靜態方法,聲明時不會把self傳遞給函數 def fun2(test): print(test) p1 = Peaple('Jack','male',22) p1.fun()
這個例子裏,就列舉了經常使用的幾個方法和屬性(習慣問題,有些時候叫方法,也有時候叫函數):
1.類變量/常量:好比這個類裏的對象都具備的屬性,咱們在抽象類的時候就能夠把他拿出來,在實例化的時候就不用再專門賦值了。通常類變量都是用大寫字母來命名。
2.類方法:用裝飾器將方法聲明爲類方法,在函數內沒法調用在構造函數中定義的屬性,只能調用上一條中的類屬性。類屬性還有另一種用法,返回一個類:
@classmethod def new_person(cls,name,sex,age): return cls(name=name,sex=sex,age=age) p1 = Peaple('Jack','male',22) p2 = p1.new_person('Mary','female',25)
咱們定義個類方法,而後能夠經過實例調用這個類方法建立一個新的實例(還沒想到有什麼實際做用)
3.靜態方法:靜態方法已經和類沒什麼關聯了,只是在調用的時候要加上類。最直觀的例子就是相似於os的模塊,導入後os裏的各個方法其實和os這個類是沒什麼關係的,可是在調用的時候仍是要加上os
import os os.open() os.close()
4.私有屬性是隻有在類裏的方法能夠調用的,而在實例中沒法調用。(一樣,在定義方法的時候加上"__"注意是兩道下劃線就構成了私有方法,也是隻能在構造類裏使用,在實例中沒法使用)。
三.繼承
繼承是面向對象裏很重要的一點,說白了就是子類具備費雷的屬性和函數。在下面一章結合實例應用裏面咱們會着重提一下,在這裏就說幾點:
1.子類在實例化的時候是不會調用父類的構造函數的,必須顯性的調用父類的構造函數,(super().__init__())。
2.其次,在某些定義的類的方法時候
class A(): def __init__(self): pass def fun(self): raise Exception('fun is not defined')
在父類定義fun的時候,這種方式定義出來的函數,在子類裏必須重構一下,不然會raise error中斷程序的執行,這種寫法叫函數重寫,可使子類必須從新寫一遍函數來蓋掉原來的函數。
3.還有一種類是抽象類,它的存在就是做爲父類存在的,一旦對象化就會報錯(就像PyQt5裏的各類基類),
from abc import ABCMeta,abstractclassmethod class A(metaclass=ABCMeta): def __init__(self): pass @abstractclassmethod def fun(self): raise Exception('fun is not defined')
在這裏A就是一個抽象類。抽象類裏能夠把全部子類的共同的方法都放進去,可是A類是不能直接實例化的。
這是軟件功能中一個很重要的概念:定義接口。大型工程每每須要不少人合做開發,在idea提出後,開發組和產品組首先召開產品設計會,PM寫出產品需求文檔,而後迭代;TL(項目經理)編寫開發文檔,開發文檔中會定義不一樣模塊的大體功能和接口、每一個模塊之間如何寫做】單元測試和繼承測試、線上灰度測試、監測和日誌等等一些列開發流程。抽象類就是這麼一種存在,他是一種自上而下的設計風範,只須要少許的代碼描述清除要作的事情,定義好接口,而後就能夠交給不一樣的開發人員去開發和對接。
4.注意繼承的順序:在之前那個帖子裏演示過了,總結了就是一句:在Python2中經典類是按照深度優先來繼承,新式類是廣度優先的繼承策略;而在Python3中經典類和新式類都是按照廣度優先的繼承策略。