Python入門系列18 - 面向?qū)ο笃?一)
Python入門系列18

面向?qū)ο笃ㄒ唬?/p>
本篇文字為3205字,閱讀時間約為13分鐘。
1
前言
廢話不多說..依然繼續(xù)回歸python入門系列知識分享,這次開始了重頭戲,就是編程屆的重要思想 --- 面向?qū)ο?沒錯,它是一種編程的思想)。時常在編程屆,經(jīng)常聽到有人說找不到女朋友怎么辦?對于程序員來說,so easy啊,直接new 一個“對象”出來就行了!而在python中,對象的概念也是非常重要的,因為在python中有著萬物即對象的概念,所有東西都可以看做是對象!今天就來演示下,如何用代碼創(chuàng)建出一個女朋友來!~(屌絲?。∥婺樑?..
)
2
面向?qū)ο缶幊?/strong>
什么是面向?qū)ο缶幊棠??之前的小課堂中,我一直在強調(diào)一個概念,就是計算機中的代碼就是現(xiàn)實世界的映射,而對象也不例外。舉個例子來說,比如現(xiàn)實世界的車,奔馳,寶馬,瑪莎拉蒂,阿斯頓·馬丁,這些品牌所造出來的車,都屬于汽車這一類型,而所謂的汽車這一類型映射到編程世界就是對象。再舉個栗子,前言說到的女朋友,也可以看做一個類型,對應(yīng)到代碼中也可以是一個對象。。所以類型,我們一般在編程中簡稱類, 類 = 面向?qū)ο蟆?/span>

3
定義一個女朋友(創(chuàng)建對象)
自己用代碼創(chuàng)建一個女朋友吧!你的女朋友,你當然知道她的姓名,年齡,身高,生日等等,這里所說的都是描述女朋友的特征,對應(yīng)到python代碼中可以理解為女票就是一個對象,而特征即為這個對象的特有屬性。
類,在Python中用class作為關(guān)鍵詞表示。下面來看下代碼演示:
class?GirlFriend():
????name?=?'女兒國國王'??????#?姓名
????age?=? 300 ?????????????#?年齡
????height?=?'177'??????????#?身高
????birthday?=?'1718-12-01'?#?出生
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????????print(f'我的身高:{self.height}')
????????print(f'我的生日:{self.birthday}')
girlFriend?=?GirlFriend()???#?實例化
girlFriend.say_feature()??#?調(diào)用對象的方法
最終輸出:
>>> 我的姓名:女兒國國王
>>> 我的年齡:300
>>> 我的身高:177
>>> 我的生日:1718-12-01
① 可以看到上述代碼段中,class 后面定義了類的名字女朋友,一般定義對象時,命名符合首字母大寫,后面每個單詞首字母大寫,編程中稱之為駝峰命名法。例如girlfriend,你就要寫成GirlFriend。名字定義完后面跟上小括號,需要注意的是小括號中只能傳入另一種對象,而非類似函數(shù)的形參。后續(xù)會講到繼承,到時候就懂了。
② 在類中,我定義了一些女朋友的特征,并且給了她一個行為,她可以自己說出自己的特征。這個行為和我們定義的函數(shù)一樣,也是通過def定義,在類中,我們可以將之成為方法,方法和函數(shù)的寫法一樣,但是概念上稍有差異。方法是從設(shè)計層面定義的,而函數(shù)是從執(zhí)行過程中設(shè)計的,了解即可。然而調(diào)用自身的屬性時,必須要在方法中傳入形參self,只有通過self.xxx才可以調(diào)用變量(name,age....),也就是特征。否則可以自行嘗試,直接調(diào)用變量名稱會報錯。
③ 如何調(diào)用,讓女朋友自己說話?girlFriend?=?GirlFriend()?通過這樣的寫法,將對象進行實例化,然后可以通過賦予的變量加以.來調(diào)用她內(nèi)部的方法??梢钥吹缴隙未a最后一行就是調(diào)用方式。
思考一個問題,當我們有一個女朋友時,此時創(chuàng)建多個實例對象會怎么樣呢?他們會屬于一個對象嗎?來看下:
girlFriend?=?GirlFriend()???#?實例化
girlFriend1?=?GirlFriend()
girlFriend2?=?GirlFriend()
還記得python中自帶的id()函數(shù)嗎,可以通過此函數(shù)來查看對應(yīng)的內(nèi)存地址,結(jié)果如下:
print(id(girlFriend))
print(id(girlFriend1))
print(id(girlFriend2))
>>>?1361650701648
>>>?1361650701760
>>>?1361650631512
顯而易見!雖然公用的是一個女票作為類來進行實例化,但是到具體的對象時,她們之間的內(nèi)存地址卻不盡相同。
4
女朋友的初始化行為(構(gòu)造函數(shù))
什么叫女朋友的初始化行為呢?還是用上面的例子來舉例說明,女兒國國王,初始的設(shè)定就是為了娶到唐僧,然后嘿嘿嘿........吃掉。來看下代碼:
class?GirlFriend():
????name?=?'女兒國國王'??????#?姓名
????age?=??300??????????????#?年齡
????height?=?'177'??????????#?身高
????birthday?=?'1718-12-01'?#?出生
????def?__init__(self):
????????print('我要先把唐僧娶了,嘿嘿嘿....然后再吃了!')
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????????print(f'我的身高:{self.height}')
????????print(f'我的生日:{self.birthday}')
????????
#?實例化時,會輸出我要先把唐僧娶了,嘿嘿嘿....然后在吃了!
girlFriend?=?GirlFriend()???
>>> 我要先把唐僧娶了,嘿嘿嘿....然后再吃了!
可以看到我在女朋友的類中新增了一個?def?__init__(self) 方法,此方法見名知意,init是初始的意思,也就是常說的構(gòu)造方法。什么意思呢?每當我們實例化對象時,默認會調(diào)用此方法,一般用于類調(diào)用時候的初始操作,比如女兒國國王的初始任務(wù)就是對唐僧下手!
需要注意的幾點如下:
①? __init__方法可以手動調(diào)用,但是沒有必要。
girlFriend?=?GirlFriend()???#?實例化
girlFriend.__init__()???????#?可以通過調(diào)用此方法看下
>>> 我要先把唐僧娶了,嘿嘿嘿....然后再吃了!
>>> 我要先把唐僧娶了,嘿嘿嘿....然后再吃了!
② __init__()的默認返回值:None
girlFriend?=?GirlFriend()???#?實例化
print(girlFriend.__init__())
print(type(girlFriend.__init__()))
>>> 我要先把唐僧娶了,嘿嘿嘿....然后再吃了!
>>> None
>>> ③ 嘗試給init添加返回值,報錯,可以看到只能返回None,不能返回其他類型。

對于女兒國國王為女朋友的例子,如果我作為她背后的黑幕,每次都想讓她的初始任務(wù)聽命于我呢,也就是所謂的每次實例化時,再將具體的任務(wù)分配給她,如何做到?于是有了下面的代碼:
class?GirlFriend():
????name?=?'女兒國國王'??????#?姓名
????age?=??300??????????????#?年齡
????height?=?'177'??????????#?身高
????birthday?=?'1718-12-01'?#?出生
????def?__init__(self,task_name):
????????print(task_name)
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????????print(f'我的身高:{self.height}')
????????print(f'我的生日:{self.birthday}')
girlFriend?=?GirlFriend('我要先把唐僧娶了,嘿嘿嘿....')???#?實例化
girlFriend1?=?GirlFriend('然后再吃了!')???#?實例化
>>> 我要先把唐僧娶了,嘿嘿嘿....
>>> 然后再吃了!
通過構(gòu)造方法的傳參,可以實現(xiàn)我們對一個對象實例化時進行可控的參數(shù)傳入。但是需要注意,如果在構(gòu)造方法處定義了參數(shù),那么實例化對象時一定要傳入對應(yīng)的數(shù)量參數(shù),否則會報錯缺少參數(shù)的錯誤,如下:

5
類變量與實例變量的對比
什么是類變量?什么是實例變量呢?還是回歸到“女兒國國王”女朋友的例子上:
class?GirlFriend():
????name?=?'女兒國國王'??????#?姓名
????age?=??300??????????????#?年齡
????height?=?'177'??????????#?身高
????birthday?=?'1718-12-01'?#?出生
????#?初始化構(gòu)造方法
????def?__init__(self,name,age):
????????self.name?=?name
????????self.age?=?age
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????????print(f'我的身高:{self.height}')
????????print(f'我的生日:{self.birthday}')
girlFriend?=?GirlFriend('人類女孩',18)???#?實例化
girlFriend.say_feature()
print(f'類變量姓名:{GirlFriend.name}')
print(f'類變量年齡:{GirlFriend.age}')
>>>?我的姓名:人類女孩
>>>?我的年齡:18
>>>?我的身高:177
>>>?我的生日:1718-12-01
>>>?類變量姓名:女兒國國王
>>>?類變量年齡:300
所謂的類變量就是指上述代碼中沒有定義在方法中的變量,而直接暴露在類中定義的變量,例如height =?'177'。實例變量是指定義在類方法中的變量,例如構(gòu)造方法中我們傳入的name和age。通常使用self.xx = xx將外界參數(shù)綁定到實例變量中??梢钥吹缴厦娲a中的結(jié)果,通過實例化傳入的變量,最終調(diào)用打印說話時,以實例變量為準,而非類變量。
Tips:
實際上,目前這個女朋友的例子中的類變量寫的并沒有實際意義,只是為了演示而演示,從設(shè)計的角度出發(fā),類變量怎么可能選擇姓名和名稱這種不固定的值呢?可以思考下,既然是類的變量,那應(yīng)該是一個種類所具體有的特征,而非具體到某一特征,比如姓名,一個人可能一生會談好幾次戀愛,每次女朋友的名字都是會變的,那你能把名字作為所有女朋友這一類共同特征嗎!肯定是不行的,所以類變量定義時應(yīng)該是選取共同特征時的變量去定義,我這里只是舉例而已。
6
總結(jié)
類最基本的作用:封裝,類就像一個模板,說白了就是代碼共用的一套寫法,而類就是現(xiàn)實世界的抽象!什么是抽象?。。〕橄笤诰幊淌澜缰芯褪菍⑺杏泄餐缘臇|西抽出來封裝成一個模板!而實例化后的對象才是具體的實現(xiàn)。(編程思想,非專業(yè)人員了解即可。)
至此完!
