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

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

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

對(duì)于女兒國(guó)國(guó)王為女朋友的例子,如果我作為她背后的黑幕,每次都想讓她的初始任務(wù)聽命于我呢,也就是所謂的每次實(shí)例化時(shí),再將具體的任務(wù)分配給她,如何做到?于是有了下面的代碼:
class?GirlFriend():
????name?=?'女兒國(guó)國(guó)王'??????#?姓名
????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('我要先把唐僧娶了,嘿嘿嘿....')???#?實(shí)例化
girlFriend1?=?GirlFriend('然后再吃了!')???#?實(shí)例化
>>> 我要先把唐僧娶了,嘿嘿嘿....
>>> 然后再吃了!
通過構(gòu)造方法的傳參,可以實(shí)現(xiàn)我們對(duì)一個(gè)對(duì)象實(shí)例化時(shí)進(jìn)行可控的參數(shù)傳入。但是需要注意,如果在構(gòu)造方法處定義了參數(shù),那么實(shí)例化對(duì)象時(shí)一定要傳入對(duì)應(yīng)的數(shù)量參數(shù),否則會(huì)報(bào)錯(cuò)缺少參數(shù)的錯(cuò)誤,如下:

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