作者m06800825 ( )
看板Python
標題[問題] 關於類別方法classmethod
時間Thu Jul 19 21:33:58 2018
想請問在以下程式碼中
定義了有兩個add方法的類別Cal
class Cal():
c = 100
def __init__(self):
pass
@classmethod
def add1(cls, a, b):
print (a + b + cls.c)
def add2(a, b):
print (a + b + Cal.c)
Cal.add1(5, 6)
Cal.add2(5, 6)
兩個函數都可以直接透過Cal.來呼叫
並且都會印出111
所以兩個都是類別方法
那add1上面加上修飾子@classmethod
引數又多寫一個cls
用這種方式來寫類別方法的用意為何呢?
這樣豈不是多此一舉?
煩請版上各位大神開釋
感激不盡!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.77.113
※ 文章網址: https://www.ptt.cc/bbs/Python/M.1532007244.A.9EF.html
→ s860134: Cal.add2(5, 6) 明顯是錯的 07/19 21:51
→ s860134: 你應該沒執行過你的範例 07/19 21:53
有跑過了! 是可以執行的! 結果會印出兩個111
※ 編輯: m06800825 (123.193.77.113), 07/19/2018 21:59:13
→ thefattiger: 好處就是你也可以透過實體呼叫add1,但add2就不行了 07/19 23:07
→ laputaflutin: 你的add2方法有問題啊,沒有self 07/19 23:17
我是想要當作類別方法用不是實體方法 所以應該要不加self吧?
→ thefattiger: 再多補一個__add__,add2就沒問題了XD 07/19 23:21
推 guaptpan: Add2可以跑沒錯,Cal.c會等於100代入運算 07/19 23:49
推 guaptpan: 還是有少@staticmethod? 突然混亂了XDD 07/20 00:00
加@staticmethod好像是靜態方法不是類別方法
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:22:48
→ s860134: a 被帶入 instance 拿去跟 int 相加惹拉,不能跑的 code 07/20 00:22
→ s860134: 你能跑一定是你 global 被汙染了,開個檔存起來執行 07/20 00:23
→ s860134: add2 沒有建 instance 是不能被呼叫 就那麼簡單... 07/20 00:24
→ s860134: "unbound method add2() must be called with ...." 07/20 00:27
→ s860134: 你剛學 class 以後你會常常看到這個錯誤... 07/20 00:27
可是剛把add1拿掉還是可以跑欸... 越來越混亂了QQ
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:31:29
→ laputaflutin: 你是不是用jupyter跑,寫一個py檔用終端跑跑看 07/20 00:33
我是用python內建的IDLE跑的 換成用Spyder也可以跑~
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:36:01
→ laputaflutin: jupyter會幫你存每次執行過的所有全局變量,跟實際 07/20 00:35
→ laputaflutin: 用py檔跑其實很不一樣 07/20 00:35
我是存成py檔來跑的沒錯
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:37:01
→ s860134: 正確來說 jupyter 真的就是個筆記本 07/20 00:36
→ s860134: 他只是幫你一行一行的丟到背後的 python 直譯器去跑 07/20 00:36
→ s860134: 所以你可以正的跑反的跑跳者跑 07/20 00:37
→ s860134: 這讓你以為你的 code 是正確的,實際上是環境髒了 07/20 00:37
我是存成py檔來跑的QQ 附上截圖
https://imgur.com/a/VuRpL7n ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:40:32
→ s860134: 靠悲 3.X 加的新功能 07/20 00:43
→ guaptpan: 真的可以執行耶,但如果用Cal建出實例new_Cal則 07/20 00:44
→ guaptpan: new_Cal.add2就會出錯 07/20 00:44
喔喔所以主要是差在add2只能用類別呼叫而不能透過實例呼叫 add1則兩者都可呼叫
這樣理解應該沒錯吧?
→ s860134: python 3.x 開始 unbound method 被視為 function 07/20 00:44
我是直接學python3的新手XD 原來是新功能RRR
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:48:43
→ guaptpan: 所以如果針對原po的問題回答的話 07/20 00:46
→ guaptpan: 有一個差別是不加@classmethod的method又不傳入self就只 07/20 00:46
→ guaptpan: 能在非實例實執行 07/20 00:46
→ guaptpan: 建成實例就會出錯 07/20 00:46
了解!!! 感謝各位陪我這個初學者討論~
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:50:56
→ s860134: 應該說你上面寫的都沒有把 instance 建出來 07/20 00:51
→ s860134: 所以感覺怎麼都一樣 07/20 00:51
所以如果用instance呼叫add2 就會因為多傳了一個self參數所以無法執行 應該沒錯吧XD
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:54:58
→ s860134: 你加個 c= Cal() 建立一個 instance 再試上面兩個 method 07/20 00:54
→ s860134: 第二個會出錯,他會跟你說你丟了3個參數但是他只吃2個 07/20 00:54
→ s860134: 對 instance 來說,第一個參數會默認放入自己 07/20 00:55
→ s860134: 另外是 type 改變了 07/20 00:55
→ s860134: 你在 ide 上面打 Cal.add2 會顯示 "function Cal.add2 at 07/20 00:56
→ s860134: c.add2 則會顯示 bound method Cal.add2 07/20 00:57
恩恩終於搞懂差別在哪了QQ 謝謝s大!
※ 編輯: m06800825 (123.193.77.113), 07/20/2018 01:00:05
→ s860134: python3 用了好一陣子現在才知道 unbound method 沒了QQ 07/20 01:01