※ 引述《jasonhsu14 (14號星期五的傑森)》之銘言:
: H1=Human1()
: print(H1.BMI())得到當初創建類別時的預設或輸入的數字
: print(H1.BMI(170,80))時,得到不一樣的結果
: 有想過直接在 def BMI(self, h=160, w=50)這樣去寫
: 但這樣又等於重複做了跟__init__一樣的事情
: 所以想詢問有無辦法讓BMI變成一個
: 不輸入的話就會根據最一開始創建類別的預設(或輸入)數值
: 但也可以讓BMI自己另外輸入想要的數字
忽然覺得想說的多了點,還是回文好了。雖然推文給了一個回答,但我覺得最好
還是從概念上來處理這個問題。
H1.BMI()
這寫法很直覺,就是得到H1這個實體本身的BMI,沒有問題。但是:
H1.BMI(170, 80)
請問你覺得這是什麼概念呢?叫H1這個人幫你算算170/80的人BMI是多少?
你可以發現,這兩個用法的概念是衝突的。前者把H1當作一個有BMI的實體,後
者卻只是一個計算BMI的計算器。
那麼我的建議是,應該把實體跟計算器的角色分開來。這個計算器誰來負責呢?
我認為是Human1 class本身,把計算方法定義成Human1的一個靜態方法。當我們要計
算任意一組資料的BMI時,我們呼叫:
Human1.cal_BMI(170, 80)
這個cal_BMI()可以定義為:
@classmethod
def cal_BMI(cls, h, w):
# 計算並return BMI
當我們要得知一個實體H1本身的BMI時,我們呼叫:
H1.BMI()
而這個BMI()則定義為:
def BMI(self):
return Human1.cal_BMI(self.h, self.w)
這樣,我們就既不需要在兩處處理default值(__init__跟BMI),也兼顧了code
的重用性,同時讓實體跟class本體的角色更明確。同時,也不需要寫煩人的邏輯來
判斷輸入值是什麼情況、要用內部值或外部值等等。
BMI要修改計算方式,我們只需要改動cal_BMI(),除非引入了其他參數或要改變
實體與類的計算連接方式(比如說,公開測量時的cal_BMI都是很公正的,但是要讓
每個人自報BMI時都故意低報一點,就像NBA球員偷偷高報身高XD)才會動到BMI()。