摘要:接下來,一般都要編寫構造函數(shù),在寫這個函數(shù)之前,先解釋一下什么是構造函數(shù)。故這個函數(shù)稱為構造函數(shù),擔負著對類進行初始化的任務。
雖然已經對類有了一點點模糊概念,但是,閱讀前面一講的內容的確感到累呀,都是文字,連代碼都沒有。
本講就要簡單多了,嘗試走一個類的流程。
說明:關于類的這部分,我參考了《Learning Python》一書的講解。
創(chuàng)建類創(chuàng)建類的方法比較簡單,如下:
class Person:
注意,類的名稱一般用大寫字母開頭,這是慣例。當然,如果故意不遵循此慣例,也未嘗不可,但是,會給別人閱讀乃至于自己以后閱讀帶來麻煩。既然大家都是靠右走的,你就別非要在路中間睡覺了。
接下來,一般都要編寫構造函數(shù),在寫這個函數(shù)之前,先解釋一下什么是構造函數(shù)。
class Person: def __init__(self, name, lang, website): self.name = name self.lang = lang self.website = website
上面的類中,首先呈現(xiàn)出來的是一個名為:__init__()的函數(shù),注意,這個函數(shù)是以兩個下劃線開始,然后是init,最后以兩個下劃線結束。這是一個函數(shù),就跟我們此前學習過的函數(shù)一樣的函數(shù)。但是,這個函數(shù)又有點奇特,它的命名是用“__”開始和結束。
請看官在這里要明確一個基本概念,類就是一種對象類型,和跟前面學習過的數(shù)值、字符串、列表等等類型一樣。比如這里構建的類名字叫做Person,那么就是我們要試圖建立一種對象類型,這種類型被稱之為Person,就如同有一種對象類型是list一樣。
在構建Person類的時候,首先要做的就是對這種類型進行初始化,也就是要說明這種類型的基本結構,一旦這個類型的對象被調用了,第一件事情就是要運行這個類型的基本結構,也就是類Person的基本結構。就好比我們每個人,在頭腦中都有關于“人”這樣一個對象類型(對應著類),一旦遇到張三(張三是一個具體人),我們首先運行“人”這個類的基本結構:一個鼻子兩只眼,鼻子下面一張嘴。如果張三符合這個基本機構,我們不會感到驚詫(不報錯),如果張三不符合這個基本結構(比如三只眼睛),我們就會感到驚詫(報錯了)。
由于類是我們自己構造的,那么基本結構也是我們自己手動構造的。在類中,基本結構是寫在__init__()這個函數(shù)里面。故這個函數(shù)稱為構造函數(shù),擔負著對類進行初始化的任務。
還是回到Person這個類,如果按照上面的代碼,寫好了,是不是__init__()就運行起來了呢?不是!這時候還沒有看到張三呢,必須看到張三才能運行。所謂看到張三,看到張三這樣一個具體的實實在在的人,此動作,在python中有一個術語,叫做實例化。當類Person實例化后立刻運行__init__()函數(shù)。
#!/usr/bin/env python #coding:utf-8 class Person: def __init__(self, name, lang, website): self.name = name self.lang = lang self.website = website info = Person("qiwsir","python","qiwsir.github.io") #實例化Person print "info.name=",info.name print "info.lang=",info.lang print "info.website=",info.website #上面代碼的運行結果: info.name= qiwsir info.lang= python info.website= qiwsir.github.io
在上面的代碼中,建立的類Person,構造函數(shù)申明了這個類的基本結構:name,lang,website。
注意觀察:info=Person("qiwsir","python","qiwsir.github.io"),這句話就是將類Person實例化了。也就是在內存中創(chuàng)建了一個對象,這個對象的類型是Person類型,這個Person類型是什么樣子的呢?就是__init__()所構造的那樣。在實例化時,必須通過參數(shù)傳入具體的數(shù)據(jù):name="qiwsir",lang="python",website="qiwsir.github.io"。這樣在內存中就存在了一個對象,這個對象的類型是Person,然后通過賦值語句,與變量info建立引用關系。請看官回憶以前已經講述過的變量和對象的引用關系。
看官是不是有點暈乎了?類、實例,這兩個概念會一直伴隨著后續(xù)的學習,并且,在很多的OOP模型中,都會遇到這兩個概念。為了讓看官不暈乎,這里將它們進行比較(注意:比較的內容,參考了《Learning Python》一書)
類和實例“類提供默認行為,是實例的工廠”,我覺得這句原話非常經典,一下道破了類和實例的關系??瓷厦娲a,體會一下,是不是這個理?所謂工廠,就是可以用同一個模子做出很多具體的產品。類就是那個模子,實例就是具體的產品。所以,實例是程序處理的實際對象。
類是由一些語句組成,但是實例,是通過調用類生成,每次調用一個類,就得到這個類的新的實例。
對于類的:class Person,class是一個可執(zhí)行的語句。如果執(zhí)行,就得到了一個類對象,并且將這個類對象賦值給對象名(比如Person)。
也許上述比較還不足以讓看官理解類和實例,沒關系,繼續(xù)學習,在前進中排除疑惑。
self的作用細心的看官可能注意到了,在構造函數(shù)中,第一個參數(shù)是self,但是在實例化的時候,似乎沒有這個參數(shù)什么事兒,那么self是干什么的呢?
self是一個很神奇的參數(shù)。
在Person實例化的過程中,數(shù)據(jù)"qiwsir","python","qiwsir.github.io"通過構造函數(shù)(__init__())的參數(shù)已經存入到內存中,并且這些數(shù)據(jù)以Person類型的面貌存在組成一個對象,這個對象和變量info建立的引用關系。這個過程也可說成這些數(shù)據(jù)附加到一個實例上。這樣就能夠以:object.attribute的形式,在程序中任何地方調用某個數(shù)據(jù),例如上面的程序中以info.name得到"qiwsir"這個數(shù)據(jù)。這種調用方式,在類和實例中經常使用,點號“.”后面的稱之為類或者實例的屬性。
這是在程序中,并且是在類的外面。如果在類的里面,想在某個地方使用傳入的數(shù)據(jù),怎么辦?
隨著學習的深入,看官會發(fā)現(xiàn),在類內部,我們會寫很多不同功能的函數(shù),這些函數(shù)在類里面有另外一個名稱,曰:方法。那么,通過類的構造函數(shù)中的參數(shù)傳入的這些數(shù)據(jù)也想在各個方法中被使用,就需要在類中長久保存并能隨時調用這些數(shù)據(jù)。為了解決這個問題,在類中,所有傳入的數(shù)據(jù)都賦給一個變量,通常這個變量的名字是self。注意,這是習慣,而且是共識,所以,看官不要另外取別的名字了。
在構造函數(shù)中的第一個參數(shù)self,就是起到了這個作用——接收實例化過程中傳入的所有數(shù)據(jù),這些數(shù)據(jù)是通過構造函數(shù)后面的參數(shù)導入的。顯然,self應該就是一個實例(準確說法是應用實例),因為它所對應的就是具體數(shù)據(jù)。
如果將上面的類增加兩句,看看效果:
#!/usr/bin/env python #coding:utf-8 class Person: def __init__(self, name, lang, website): self.name = name self.lang = lang self.website = website print self #打印,看看什么結果 print type(self) #運行結果 <__main__.Person instance at 0xb74a45cc>
證實了推理。self就是一個實例(準確說是實例的引用變量)。
self這個實例跟前面說的那個info所引用的實例對象一樣,也有屬性。那么,接下來就規(guī)定其屬性和屬性對應的數(shù)據(jù)。上面代碼中:self.name = name,就是規(guī)定了self實例的一個屬性,這個屬性的名字也叫做name,這個屬性的數(shù)據(jù)等于構造函數(shù)的參數(shù)name所導入的數(shù)據(jù)。注意,self.name中的name和構造函數(shù)的參數(shù)name沒有任何關系,它們兩個一樣,只不過是一種起巧合(經常巧合),或者說是寫代碼的人懶惰,不想另外取名字而已,無他。當然,如果寫成self.xxxooo = name,也是可以的。
其實,從效果的角度來理解,可能更簡單一些,那就是類的實例info對應著self,info通過self導入實例屬性的所有數(shù)據(jù)。
當然,self的屬性數(shù)據(jù),也不一定非得是由參數(shù)傳入的,也可以在構造函數(shù)中自己設定。比如:
#!/usr/bin/env python #coding:utf-8 class Person: def __init__(self, name, lang, website): self.name = name self.lang = lang self.website = website self.email = "qiwsir@gmail.com" #這個屬性不是通過參數(shù)傳入的 info = Person("qiwsir","python","qiwsir.github.io") print "info.name=",info.name print "info.lang=",info.lang print "info.website=",info.website print "info.email=",info.email #info通過self建立實例,并導入實例屬性數(shù)據(jù) #運行結果 info.name= qiwsir info.lang= python info.website= qiwsir.github.io info.email= qiwsir@gmail.com #打印結果
通過這個例子,其實讓我們拓展了對self的認識,也就是它不僅僅是為了在類內部傳遞參數(shù)導入的數(shù)據(jù),還能在構造函數(shù)中,通過self.attribute的方式,規(guī)定self實例對象的屬性,這個屬性也是類實例化對象的屬性,即做為類通過構造函數(shù)初始化后所具有的屬性。所以在實例info中,通過info.email同樣能夠得到該屬性的數(shù)據(jù)。在這里,就可以把self形象地理解為“內外兼修”了?;蛘甙凑涨懊嫠岬降?,將info和self對應起來,self主內,info主外。
其實,self的話題還沒有結束,后面的方法中還會出現(xiàn)它。它真的神奇呀。
構造函數(shù)的參數(shù)前面已經說過了,構造函數(shù)__init__就是一個函數(shù),只不過長相有點古怪罷了。那么,函數(shù)中的操作在構造函數(shù)中依然可行。比如:
def __init__(self,*args): pass
這種類型的參數(shù):*args和前面講述函數(shù)參數(shù)一樣,就不多說了。忘了的看官,請去復習。但是,self這個參數(shù)是必須的,因為它要來建立實例對象。
很多時候,并不是每次都要從外面?zhèn)魅霐?shù)據(jù),有時候會把構造函數(shù)的某些參數(shù)設置默認值,如果沒有新的數(shù)據(jù)傳入,就應用這些默認值。比如:
class Person: def __init__(self, name, lang="golang", website="www.google.com"): self.name = name self.lang = lang self.website = website self.email = "qiwsir@gmail.com" laoqi = Person("LaoQi") #導入一個數(shù)據(jù)name="LaoQi",其它默認值 info = Person("qiwsir",lang="python",website="qiwsir.github.io") #全部重新導入數(shù)據(jù) print "laoqi.name=",laoqi.name print "info.name=",info.name print "-------" print "laoqi.lang=",laoqi.lang print "info.lang=",info.lang print "-------" print "laoqi.website=",laoqi.website print "info.website=",info.website #運行結果 laoqi.name= LaoQi info.name= qiwsir ------- laoqi.lang= golang info.lang= python ------- laoqi.website= www.google.com info.website= qiwsir.github.io
在這段代碼中,看官首先要體會一下,“類是實例的工廠”這句話的含義,通過類Person生成了兩個實例:laoqi、info
此外,在看函數(shù)賦值的情況,允許設置默認參數(shù)值。
至此,僅僅是初步構建了一個類的基本結構,完成了類的初始化。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/37397.html
摘要:是一個具體的數(shù)據(jù),通過構造函數(shù)中的參數(shù),傳給實例的屬性,在類中的另外一個方法的參數(shù)列表中第一個就是,表示要承接對象,,就是在類內部通過對象,把它的屬性的數(shù)據(jù)傳導如。 上一講中創(chuàng)建了類,并且重點講述了構造函數(shù)以及類實例,特別是對那個self,描述了不少。在講述構造函數(shù)的時候特別提到,init()是一個函數(shù),只不過在類中有一點特殊的作用罷了,每個類,首先要運行它,它規(guī)定了類的基本結構。 ...
摘要:在對象接口后包裝其實現(xiàn)的細節(jié),從而隔離了代碼的修改對用戶產生的影響。類提供了一個新的本地作用域,最小化了變量名沖突。類其實并沒有結束,不過本講座到此對類暫告一段。 前面對類的有關內容已經描述不少了,其實話題遠遠沒有結束,不過對于初學者,掌握這些已經算是入門,在以后的實踐中,還需要進行體會和感悟。 這幾天和幾個朋友以各種途徑討論過OOP的相關問題,他們是:令狐蟲、Frank、晉劍、小馮...
摘要:從運行結果可以看出,當子類繼承多個父類的時候,對于構造函數(shù),只有第一個能夠被繼承,第二個就等掉了。重點看,類繼承了,同時,在構造函數(shù)中自己做了規(guī)定,也就是的構造函數(shù)是按照的意愿執(zhí)行,不執(zhí)行的內容,但是,還有一個方法,則繼承了這個方法。 在上一講代碼的基礎上,做進一步修改,成為了如下程序,請看官研習這個程序: #!/usr/bin/env python #coding:utf-8 c...
摘要:反對者在某些領域對此予以否認。下面再引用一段來自維基百科中關于的歷史。類的更嚴格的定義是由某種特定的元數(shù)據(jù)所組成的內聚的包。類還可以有運行時表示形式元對象,它為操作與類相關的元數(shù)據(jù)提供了運行時支持。 在開始部分,請看官非常非常耐心地閱讀下面幾個枯燥的術語解釋,本來這不符合本教程的風格,但是,請看官諒解,因為列位將來一定要閱讀枯燥的東西的。這些枯燥的屬于解釋,均來自維基百科。 1、問題...
閱讀 1546·2021-11-24 09:39
閱讀 3756·2021-11-24 09:39
閱讀 1939·2021-11-16 11:54
閱讀 1540·2021-09-30 09:47
閱讀 1820·2021-09-26 10:16
閱讀 2397·2021-09-22 15:33
閱讀 1530·2021-09-14 18:01
閱讀 2526·2021-09-07 09:59