資料流轉過程
除了在類中可以寫這種函數之外,在類中還可以寫別的函數,延續上一講的例子:
複製代碼 代碼如下:
#!/usr/bin/env python
#coding:utf-8
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"
def author(self):
return self.name
laoqi = Person("LaoQi")
info = Person("qiwsir",lang="python",website="qiwsir.github.io")
print "Author name from laoqi:",laoqi.author()
print "Author name from info:",info.author()
#運行結果
Author name from laoqi: LaoQi
Author name from info: qiwsir
看官可能已經注意了,這段代碼比上一講多了一個函數author(self),這個我們先不管,稍後會詳細分解。首先看看資料是如何在這個代碼中流轉的。為了能夠清楚,畫一張圖,所謂一圖勝千言萬語,有圖有真相。
定義類Person,然後建立執行個體laoqi=Person("LaoQi"),看官注意觀察圖上的箭頭方向。laoqi這個執行個體和Person類中的self對應,它們都是引用了執行個體對象(很多時候簡化說成是執行個體對象)。"LaoQi"是一個具體的資料,通過建構函式中的name參數,傳給執行個體的屬性self.name,在類Person中的另外一個方法author的參數列表中第一個就是self,表示要承接self對象,return self.name,就是在類內部通過self對象,把它的屬性self.name的資料傳導如author。
當運行laoqi.author()的時候,就是告訴上面的代碼,調用laoqi執行個體對象,並得到author()方法的結果,laoqi這個執行個體就自動被告訴了author()(注意,self參數在這裡不用寫,這個告訴過程是python自動完成的,不用我們操心了),author方法就返回laoqi執行個體的屬性,因為前面已經完成了laoqi與self的對應過程,所以這時候author裡面的self就是laoqi,自然self.name=laoqi.name。
看官可以跟隨我在做一個實驗,那就是在author中,return laoqi.name,看看什麼效果。因為既然laoqi和self是同一個執行個體對象,直接寫成laoqi.name是不是也可以呢?
複製代碼 代碼如下:
#!/usr/bin/env python
#coding:utf-8
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"
def author(self):
#return self.name
return laoqi.name #返回
laoqi = Person("LaoQi")
info = Person("qiwsir",lang="python",website="qiwsir.github.io")
print "Author name from laoqi:",laoqi.author()
print "Author name from info:",info.author()
#輸出結果
Author name from laoqi: LaoQi #laoqi執行個體輸出結果
Author name from info: LaoQi #info執行個體輸出結果
從結果中可以看出,沒有報錯。但是,info這個執行個體輸出的結果和laoqi執行個體輸出的結果一樣。原來,當調用了info執行個體之後,運行到author(),返回的是laoqi.name。所以,這裡一定要用self執行個體。在調用不同的執行個體時,self會自動的進行匹配,當然,匹配過程是python完成,仍然不用我們操心。
OK,資料流轉過程,看官是否理解了呢?下面進入方法編寫的環節
為什麼要用到方法
在類裡面,可以用def語句來編寫函數,但是,通常這個函數的樣子是這樣的:
複製代碼 代碼如下:
class ClassName:
def __init__(self,*args):
...
def method(self,*args): #是一個在類裡面的函數
...
在類ClassName裡面,除了前面那個具有初始化功能的建構函式之外,還有一個函數method,這個函數和以前學習過的函數一樣,函數裡面要寫什麼,也沒有特別的規定。但是,這個函數的第一個參數必須是self,或者說,可以沒有別的參數,但是self是必須寫上並且是第一個。這個self參數的作用前面已經說過了。
這樣看來,類裡面的這個函數還有點跟以前函數不同的地方。
類裡面的這個函數,我們就稱之為方法。
之所以用方法,也是用類的原因,也是用函數的原因,都是為了減少代碼的冗餘,提高代碼的重用性,這也是OOP的原因。
方法怎樣被重用呢?看本最開始的那段代碼,裡面有一個author方法,不管是laoqi還是info執行個體,都用這個方法返回執行個體匯入的名字。這就是體現了重用。
編寫和操作方法
編寫方法的過程和編寫一個函數的過程一樣,需要注意的就是要在參數列表中第一個寫上self,即使沒有其它的參數。
複製代碼 代碼如下:
#!/usr/bin/env python
#coding:utf-8
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"
def author(self, address):
#return self.name
return laoqi.name+" in "+address
laoqi = Person("LaoQi")
info = Person("qiwsir",lang="python",website="qiwsir.github.io")
print "Author name from laoqi:",laoqi.author("China")
print "Author name from info:",info.author("Suzhou")
#運行結果
Author name from laoqi: LaoQi in China
Author name from info: LaoQi in Suzhou
這段代碼中,對author方法增加了一個參數address,當調用這個方法的時候:laoqi.author("China"),要對這個參數賦值,看官特別注意,在類中,這個方法顯示是有兩個參數(self,address),但是在調用的時候,第一個參數是自動將執行個體laoqi與之對應起來,不需要顯化賦值,可以理解成是隱含完成的(其實,也可以將laoqi看做隱藏的主體,偷偷地更self勾搭上了)。
通過上面的講述,看官可以試試類了。提醒,一定要對類的資料流通過程清晰。