[問題] 關於類別方法classmethod

看板Python作者 ( )時間7年前 (2018/07/19 21:34), 7年前編輯推噓3(3035)
留言38則, 4人參與, 7年前最新討論串1/1
想請問在以下程式碼中 定義了有兩個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

07/19 21:51, 7年前 , 1F
Cal.add2(5, 6) 明顯是錯的
07/19 21:51, 1F

07/19 21:53, 7年前 , 2F
你應該沒執行過你的範例
07/19 21:53, 2F
有跑過了! 是可以執行的! 結果會印出兩個111 ※ 編輯: m06800825 (123.193.77.113), 07/19/2018 21:59:13

07/19 23:07, 7年前 , 3F
好處就是你也可以透過實體呼叫add1,但add2就不行了
07/19 23:07, 3F

07/19 23:17, 7年前 , 4F
你的add2方法有問題啊,沒有self
07/19 23:17, 4F
我是想要當作類別方法用不是實體方法 所以應該要不加self吧?

07/19 23:21, 7年前 , 5F
再多補一個__add__,add2就沒問題了XD
07/19 23:21, 5F

07/19 23:49, 7年前 , 6F
Add2可以跑沒錯,Cal.c會等於100代入運算
07/19 23:49, 6F

07/20 00:00, 7年前 , 7F
還是有少@staticmethod? 突然混亂了XDD
07/20 00:00, 7F
加@staticmethod好像是靜態方法不是類別方法 ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:22:48

07/20 00:22, 7年前 , 8F
a 被帶入 instance 拿去跟 int 相加惹拉,不能跑的 code
07/20 00:22, 8F

07/20 00:23, 7年前 , 9F
你能跑一定是你 global 被汙染了,開個檔存起來執行
07/20 00:23, 9F

07/20 00:24, 7年前 , 10F
add2 沒有建 instance 是不能被呼叫 就那麼簡單...
07/20 00:24, 10F

07/20 00:27, 7年前 , 11F
"unbound method add2() must be called with ...."
07/20 00:27, 11F

07/20 00:27, 7年前 , 12F
你剛學 class 以後你會常常看到這個錯誤...
07/20 00:27, 12F
可是剛把add1拿掉還是可以跑欸... 越來越混亂了QQ ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:31:29

07/20 00:33, 7年前 , 13F
你是不是用jupyter跑,寫一個py檔用終端跑跑看
07/20 00:33, 13F
我是用python內建的IDLE跑的 換成用Spyder也可以跑~ ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:36:01

07/20 00:35, 7年前 , 14F
jupyter會幫你存每次執行過的所有全局變量,跟實際
07/20 00:35, 14F

07/20 00:35, 7年前 , 15F
用py檔跑其實很不一樣
07/20 00:35, 15F
我是存成py檔來跑的沒錯 ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:37:01

07/20 00:36, 7年前 , 16F
正確來說 jupyter 真的就是個筆記本
07/20 00:36, 16F

07/20 00:36, 7年前 , 17F
他只是幫你一行一行的丟到背後的 python 直譯器去跑
07/20 00:36, 17F

07/20 00:37, 7年前 , 18F
所以你可以正的跑反的跑跳者跑
07/20 00:37, 18F

07/20 00:37, 7年前 , 19F
這讓你以為你的 code 是正確的,實際上是環境髒了
07/20 00:37, 19F
我是存成py檔來跑的QQ 附上截圖https://imgur.com/a/VuRpL7n ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:40:32

07/20 00:43, 7年前 , 20F
靠悲 3.X 加的新功能
07/20 00:43, 20F

07/20 00:44, 7年前 , 21F

07/20 00:44, 7年前 , 22F
真的可以執行耶,但如果用Cal建出實例new_Cal則
07/20 00:44, 22F

07/20 00:44, 7年前 , 23F
new_Cal.add2就會出錯
07/20 00:44, 23F
喔喔所以主要是差在add2只能用類別呼叫而不能透過實例呼叫 add1則兩者都可呼叫 這樣理解應該沒錯吧?

07/20 00:44, 7年前 , 24F
python 3.x 開始 unbound method 被視為 function
07/20 00:44, 24F
我是直接學python3的新手XD 原來是新功能RRR ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:48:43

07/20 00:46, 7年前 , 25F
所以如果針對原po的問題回答的話
07/20 00:46, 25F

07/20 00:46, 7年前 , 26F
有一個差別是不加@classmethod的method又不傳入self就只
07/20 00:46, 26F

07/20 00:46, 7年前 , 27F
能在非實例實執行
07/20 00:46, 27F

07/20 00:46, 7年前 , 28F
建成實例就會出錯
07/20 00:46, 28F

07/20 00:47, 7年前 , 29F
了解!!! 感謝各位陪我這個初學者討論~ ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:50:56

07/20 00:51, 7年前 , 30F
應該說你上面寫的都沒有把 instance 建出來
07/20 00:51, 30F

07/20 00:51, 7年前 , 31F
所以感覺怎麼都一樣
07/20 00:51, 31F
所以如果用instance呼叫add2 就會因為多傳了一個self參數所以無法執行 應該沒錯吧XD ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 00:54:58

07/20 00:54, 7年前 , 32F
你加個 c= Cal() 建立一個 instance 再試上面兩個 method
07/20 00:54, 32F

07/20 00:54, 7年前 , 33F
第二個會出錯,他會跟你說你丟了3個參數但是他只吃2個
07/20 00:54, 33F

07/20 00:55, 7年前 , 34F
對 instance 來說,第一個參數會默認放入自己
07/20 00:55, 34F

07/20 00:55, 7年前 , 35F
另外是 type 改變了
07/20 00:55, 35F

07/20 00:56, 7年前 , 36F
你在 ide 上面打 Cal.add2 會顯示 "function Cal.add2 at
07/20 00:56, 36F

07/20 00:57, 7年前 , 37F
c.add2 則會顯示 bound method Cal.add2
07/20 00:57, 37F
恩恩終於搞懂差別在哪了QQ 謝謝s大! ※ 編輯: m06800825 (123.193.77.113), 07/20/2018 01:00:05

07/20 01:01, 7年前 , 38F
python3 用了好一陣子現在才知道 unbound method 沒了QQ
07/20 01:01, 38F
文章代碼(AID): #1RK9DCdl (Python)
文章代碼(AID): #1RK9DCdl (Python)