菜鳥學Python之面向對象

    在講解Python面向對象之前,我們先了解一下Python閉包的概念。什麼是Python閉包?它是用來做什麼的?

    簡單說,閉包就是根據不同的配置信息得到不同的結果。沒聽明白?那麼看一下專業的解釋:閉包是詞法閉包的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開創造它的環境也不例外。即:閉包就是由函數和與其相關的引用環境組合而成的實體。

       還是沒懂?沒關係(這麼官方的語言誰能明白,是吧)。讓我來舉例說明,這樣我們就會明白的很透徹了。

其運行結果爲:

       我們發現,make_inf是一個函數,包括一個參數name,比較特殊的地方就是這個函數裏邊有定義了一個新的函數,這個新的函數裏面的一個變量正好是外部make_inf的參數,也就是說,外部傳遞過來的name已經和inf函數綁定在一起了,形成一個新的函數,我們可以把name看作新函數的一個一個配置信息,配置信息不同,函數的功能就不一樣了,也就是能得到定製之後的函數。

       再看看運行結果,因爲配置信息不同,p,q在執行相同的參數的函數後得到了不同的結果,這就是閉包。

       通過這個例子,我們可以給閉包一個言簡意賅的定義:如果在一個內部函數裏,對在外部作用域(但不是在全局作用域)的變量進行引用,那麼內部函數就被認爲是閉包(closure).

       說了這麼多,閉包有何用途呢?

       用途1,當閉包執行完後,仍然能夠保持住當前的運行環境。

       用途2,閉包可以根據外部作用域的局部變量來得到不同的結果,這有點像一種類似配置功能的作用。

       好了,我們言歸正傳,開始講Python面向對象的基本概念:

       1、類是屬性相近的對象的歸類

       Python通過使用類(class)和對象(object)來實現面向對象的編程(OOP)。

       面向對象編程最主要的目的就是提高程序的重複使用性,這和函數的目的是相似的。

       我們從第二講就切入Python面向編程的原因是:Python的整個概念是基於對象的。瞭解OOP對我們深入瞭解Python非常之關鍵,讓我們由淺入深開始瞭解Python的面向對象編程:

       在人們的潛意識中,會把屬性相近的東西歸類,並且給類別命名。比如說人的共同屬性都有名字,都會說話。具體到個人都是以人類的原型爲基礎的。

       面向對象就是模擬了以上人類認知的過程。

       先定義人類:

      

       我們定義了一個類別(person),兩個變量:have_name,have_talk。這兩個變量對應於剛纔所說的屬性。

       假設我有一個同學,叫melody,使用前面定義的類:

      

       通過創建對象,並說明melody是類別人中的一個對象,melody就有了人的屬性,對屬性的引用通過melody.attribute的形式實現。

       2、屬性可以是變量,也可以是動作,也稱之爲方法

       在我們的日常認知中,不僅會通過變量來識別類別,還會根據這個東西能幹什麼來區分類別,比如說人可以學習,這樣就和別的動物區分開來。爲了正式一些,我們叫這樣的一些屬性稱爲方法,Python中通過在類內部定義函數,來說明方法。

      

       我們重新定義了人這個類別。

       新增了一個方法屬性。就是學習,它的參數有一個是self,它是爲了方便我們引用對象自身,而且第一個參數必須是self,在任何情況下都要這樣,而且這個參數指的就是對象本身,由於對象擁有類的所有性質,那麼我們就可以在方法內部通過self來調用類的其它屬性。

       3、類別本身還可以進一步細分成爲子類

       比如,人類可以按地域進一步劃分爲中國人和美國人

       在OOP中,我們通過繼承來表達上述概念。

      

 

       通過繼承製度,我們可以避免程序中的重複信息和重複語句。如果我們定義了兩個類,而不繼承人類,那麼我們就必須把人類的屬性分別敲到中國人和美國人類的定義中,麻煩不麻煩,所以,從剛開始就說,面向對象提高了程序的重複使用性。

       在此呢,我順便說一下面向對象和麪向過程的一些區別:

       我們可以看到,面向對象實際上基於人類認知時的習慣,將各種各樣的東西分類,從而瞭解世界。我們從祖先開始可能已經練習了這個認知過程有幾百萬年,所以面向對象是很符合人類思維習慣的編程方法。所謂面向過程(也就是執行完一個語句再執行下一個)實際上是機器思維。通過面向對象的編程,我們實際上是更貼近我們自然的思維方式,也更方便和其他人交流我們程序裏所包含的想法,甚至於那個人並不是程序員。

       下面我們來講一下類中的一些方法:

       1)__init__()方法:

       __init__()是一個非常之特殊的方法。Python裏會有一些特殊的方法,Python會以特別的方式處理它們,特殊方法的名字的特點是前後都有兩個下劃線。__init__()方法特殊的地方在於,一旦你根據這個類建立對象,Python就會自動調用這個方法(相當於初始函數)。

      

       2)、類方法

       類方法:類方法與普通的成員函數和靜態函數有不同之處,在接觸的語言中好像也沒見過這種語義,看它的定義: 一個類方法就可以通過類或它的實例來調用的方法,不管你是用類來調用這個方法還是類實例調用這個方法,該方法的第一個參數總是定義該方法的類對象。 

類方法的另一個作用就是可以對類屬性進行修改:

3)、靜態方法

要在類中使用靜態方法,需在類成員函數前面加上@staticmethod標記符,以表示下面的成員函數是靜態函數。使用靜態方法的好處是,不需要定義實例即可使用這個方法。另外,多個實例共享此靜態方法。

其結果爲:

關於Python的繼承和多繼承:

1)在Python中,如果父類和子類都重新定義了構造方法__init( )__,在進行子類實例化的時候,子類的構造方法不會自動調用父類的構造方法,必須在子類中顯示調用。

class SubClass(SuperClass1)

2)如果需要在子類中調用父類的方法,需要以  父類名.方法  這種方式調用,以這種方式調用的時候,注意要傳遞self參數過去。

  對於繼承關係,子類繼承了父類所有的公有屬性和方法,可以在子類中通過父類名來調用,而對於私有的屬性和方法,子類是不進行繼承的,因此在子類中是無法通過父類名來訪問的。

  對於多重繼承,比如

class SubClass(SuperClass1,SuperClass2)

此時有一個問題就是如果SubClass沒有重新定義構造方法,它會自動調用哪個父類的構造方法?這裏記住一點:以第一個父類爲中心。如果SubClass重新定義了構造方法,需要顯示去調用父類的構造方法,此時調用哪個父類的構造方法由你自己決定;若SubClass沒有重新定義構造方法,則只會執行第一個父類的構造方法。並且若SuperClass1和SuperClass2中有同名的方法,通過子類的實例化對象去調用該方法時調用的是第一個父類中的方法。

關於Python面向對象編程的繼承和多繼承,將在下講詳細說明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章