Python學習筆記5——一切皆對象
- 2020 年 1 月 19 日
- 筆記
我發現我不適合看影片學習,看書看文字覺得更舒服,看大神的部落格教程:Python快速教程——這是大神的第一篇部落格,點擊下一篇,一篇篇看下去,都很通俗易懂,坐看看大神是如何成長的,可以利用碎片時間看,收穫很多,不再迷茫。
另外,下面的評論也很有乾貨,值得認真看看,也會有收穫。
需要注意的是,大神用的是Python2.x,而我用的是python3.6,部分程式碼可能會有區別,但思想是一脈相承的,這個有些評論里有提到的。
主要通過這裡的部落格學習的:Python基礎08 面向對象的基本概念 以及 Python基礎09 面向對象的進一步拓展。
Python使用類(class)和對象(object),進行面向對象(object-oriented programming,簡稱OOP)的編程。面向對象的最主要目的是提高程式的重複使用性。Python的整個概念是基於對象的。了解OOP是進一步學習Python的關鍵。下面是對面向對象的一種理解,基於分類。
相近對象,歸為類
在人類認知中,會根據 屬性相近 把東西 歸類 ,並給類命名。比如鳥類,其共同屬性有:有羽毛,卵生等。
面向對象就是模擬了以上人類認知過程。上面的『東西』,在python中就稱為對象(object)。
下面貼程式碼:
""" 定義一個類別class,就是鳥類Bird。在隸屬於這個類比的語句塊中,定義了兩個變數,一個是有羽毛have_feather,一個是生殖方式way_of_reproduction,這兩個變數就是鳥類Bird的屬性attribute """ class Bird(object): have_feather = True way_of_reproduction = 'egg' """ 創建y一個對象,小雞summer,類別鳥中的一個對象,summer就有了鳥類的屬性,對屬性的引用是通過 對象.屬性 object.attribute 的形式實現的 """ summer = Bird() print(summer.have_feather, summer.way_of_reproduction)
日常認知中,我們在通過屬性識別類別的時候,有時根據這個東西能做什麼事情來區分類別。比如說,鳥會移動。這樣,鳥就和房屋的類別區分開了。這些動作會帶來一定的結果,比如移動導致位置的變化。
這樣的一些「行為」屬性為方法(method)。Python中通過在類的內部定義函數,來說明方法。
""" 重新定義鳥這個類別,新增一個方法屬性,就是表示移動的方法move,它的參數中有一個self,它是為了方便我們引用對象自身。方法的第一個參數必須是self,無論是否用到。 另外兩個參數,dx, dy表示在x、y兩個方向移動的距離。move方法會最終返回運算過的position。在最後調用move方法的時候,我們只傳遞了dx和dy兩個參數,不需要傳遞self參數(因為self只是為了內部使用)。
""" class Bird(object): have_feather = True way_of_reproduction = 'egg' def move(self, dx, dy): position = [0,0] position[0] = position[0] + dx position[1] = position[1] + dy return position summer = Bird() print('after move:',summer.move(5,8))
子類
類別本身還可以進一步細分成子類,比如鳥類可以進一步分為雞,大雁,黃鸝等。
在OOP面向對象編程中,可以通過 繼承(inheritance) 來表達上述概念:
class Chicken(Bird): way_of_move = 'walk' possible_in_KFC = True class Oriole(Bird): way_of_move = 'fly' possible_in_KFC = False summer = Chicken() print(summer.have_feather) print(summer.move(5,8))
新定義的雞Chicken類的,增加了兩個屬性:移動方式way_of_move,可能在KFC找到possible_in_KFC
在類定義時,括弧里為Bird。這說明,Chicken是屬於鳥類Bird的一個子類,即Chicken 繼承 自Bird。自然而然,Bird就是Chicken的父類。Chicken將享有Bird的所有屬性。儘管只聲明了summer是雞類,但它通過繼承享有了父類的屬性(無論是變數屬性have_feather還是方法屬性move)
新定義的黃鸝Oriole類,同樣繼承自鳥類。在創建一個黃鸝對象時,該對象自動擁有鳥類的屬性。
通過繼承製度,可以減少程式中的重複資訊和重複語句。如果分別定義兩個類,而不繼承自鳥類,就必須把鳥類的屬性分別輸入到雞類和黃鸝類的定義中。整個過程會變得繁瑣,因此,面向對象提高了程式的可重複使用性。
定義鳥類時括弧中的object,當括弧中為object時,說明這個類沒有父類,到頭了,可以把object也看作是一個類,它也有(類的)屬性和方法,可以為子類所繼承
將各種各樣的東西分類,從而了解世界,從人類祖先開始,我們就在練習了這個認知過程,面向對象是符合人類思維習慣的。所謂面向過程,也就是執行完一個語句再執行下一個,更多的是機器思維。通過面向對象的編程,我們可以更方便的表達思維中的複雜想法。
調用類的其它資訊
在定義方法時,必須有self這一參數。這個參數表示某一對象,對象擁有類的所有性質,可以通過self,調用類屬性。似乎使用在定義類內部方法的時候,類似函數的形參,是這樣嗎?
class Human(object): laugh = 'hahahaha' def show_laugh(self): print(self.laugh) def laugh_100th(self): for i in range(100): self.show_laugh() li_lei = Human() li_lei.laugh_100th()
這裡有一個類屬性laugh。在方法show_laugh()中,通過self.laugh,調用了該屬性的值。還可以用相同的方式調用其它方法。方法show_laugh(),在方法laugh_100th中()被調用。
通過對象可以修改類屬性值。但這是危險的。類屬性被所有同一類及其子類的對象共享。類屬性值的改變會影響所有的對象。
__init__()方法
__init__()是一個特殊方法(special method)。Python有一些特殊方法。Python會特殊的對待它們。特殊方法的特點是名字前後有兩個下劃線。如果你在類中定義了__init__()這個方法,創建對象時,Python會自動調用 這個方法。這個過程也叫初始化。
class happyBird(Bird): def __init__(self,more_words): print('We are happy birds.',more_words) summer = happyBird('Happy!Happy!') # 執行結果 # We are happy birds. Happy!Happy!
我們看到,儘管我們只是創建了summer對象,但__init__()方法被自動調用了。最後一行的語句(summer = happyBird…)先創建了對象,然後執行:
summer.__init__(more_words)
'Happy!Happy!' 被傳遞給了__init__()的參數more_words
對象的性質
上面講到了許多屬性,但這些屬性是類的屬性。所有屬於該類的對象會共享這些屬性。比如說,鳥都有羽毛,雞都不會飛。
在一些情況下,定義對象的性質,用於記錄該對象的特別資訊。比如說,人這個類。性別是某個人的一個性質,不是所有的人類都是男,或者都是女。這個性質的值隨著對象的不同而不同。李雷是人類的一個對象,性別是男;韓美美也是人類的一個對象,性別是女。
當定義類的方法時,必須要傳遞一個self的參數。這個參數指代的就是類的一個對象。我們可以通過操縱self,來修改某個對象的性質。比如用類來新建一個對象,即下面例子中的li_lei, 那麼li_lei就被self表示。我們通過賦值給self.attribute,給li_lei這一對象增加一些性質,比如說性別的男女。self會傳遞給各個方法。在方法內部,可以通過引用self.attribute,查詢或修改對象的性質。
這樣,在類屬性的之外,又給每個對象增添了各自特色的性質,從而能描述多樣的世界。
class Human(object): def __init__(self, input_gender): self.gender = input_gender def printGender(self): print(self.gender) li_lei = Human('male') # 這裡,'male'作為參數傳遞給__init__()方法的input_gender變數。 print(li_lei.gender) li_lei.printGender() # 執行結果 # male # male
在初始化中,將參數input_gender,賦值給對象的性質,即self.gender。
li_lei擁有了對象性質gender。gender不是一個類屬性。Python在建立了li_lei這一對象之後,使用li_lei.gender這一對象性質,專門儲存屬於對象li_lei的特有資訊。
對象的性質也可以被其它方法調用,調用方法與類屬性的調用相似,正如在printGender()方法中的調用。
總結
嗯,多做總結是個好習慣!!!佩服大神
將東西根據屬性歸類 -> 將object歸為class
方法也是一種屬性,如動作
用繼承來說明父類-子類關係,子類自動具有父類的所有屬性。
self代表了根據類定義而創建的對象。
建立一個對象:對象名 = 類名()
引用對象屬性:object.attribute
通過self調用類屬性
__init__():在建立對象時自動執行
類屬性與對象屬性,即與對象的性質的區別
最後回過頭來看看,一切皆對象,"Everything is Object"。
Python基礎10 反過頭來看看,就這樣吧!