作者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://webptt.com/cn.aspx?n=bbs/Python/M.1532007244.A.9EF.html
1F:→ s860134: Cal.add2(5, 6) 明显是错的 07/19 21:51
2F:→ s860134: 你应该没执行过你的范例 07/19 21:53
有跑过了! 是可以执行的! 结果会印出两个111
※ 编辑: m06800825 (123.193.77.113), 07/19/2018 21:59:13
3F:→ thefattiger: 好处就是你也可以透过实体呼叫add1,但add2就不行了 07/19 23:07
4F:→ laputaflutin: 你的add2方法有问题啊,没有self 07/19 23:17
我是想要当作类别方法用不是实体方法 所以应该要不加self吧?
5F:→ thefattiger: 再多补一个__add__,add2就没问题了XD 07/19 23:21
6F:推 guaptpan: Add2可以跑没错,Cal.c会等於100代入运算 07/19 23:49
7F:推 guaptpan: 还是有少@staticmethod? 突然混乱了XDD 07/20 00:00
加@staticmethod好像是静态方法不是类别方法
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:22:48
8F:→ s860134: a 被带入 instance 拿去跟 int 相加惹拉,不能跑的 code 07/20 00:22
9F:→ s860134: 你能跑一定是你 global 被污染了,开个档存起来执行 07/20 00:23
10F:→ s860134: add2 没有建 instance 是不能被呼叫 就那麽简单... 07/20 00:24
11F:→ s860134: "unbound method add2() must be called with ...." 07/20 00:27
12F:→ s860134: 你刚学 class 以後你会常常看到这个错误... 07/20 00:27
可是刚把add1拿掉还是可以跑欸... 越来越混乱了QQ
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:31:29
13F:→ laputaflutin: 你是不是用jupyter跑,写一个py档用终端跑跑看 07/20 00:33
我是用python内建的IDLE跑的 换成用Spyder也可以跑~
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:36:01
14F:→ laputaflutin: jupyter会帮你存每次执行过的所有全局变量,跟实际 07/20 00:35
15F:→ laputaflutin: 用py档跑其实很不一样 07/20 00:35
我是存成py档来跑的没错
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:37:01
16F:→ s860134: 正确来说 jupyter 真的就是个笔记本 07/20 00:36
17F:→ s860134: 他只是帮你一行一行的丢到背後的 python 直译器去跑 07/20 00:36
18F:→ s860134: 所以你可以正的跑反的跑跳者跑 07/20 00:37
19F:→ s860134: 这让你以为你的 code 是正确的,实际上是环境脏了 07/20 00:37
我是存成py档来跑的QQ 附上截图
https://imgur.com/a/VuRpL7n
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:40:32
20F:→ s860134: 靠悲 3.X 加的新功能 07/20 00:43
22F:→ guaptpan: 真的可以执行耶,但如果用Cal建出实例new_Cal则 07/20 00:44
23F:→ guaptpan: new_Cal.add2就会出错 07/20 00:44
喔喔所以主要是差在add2只能用类别呼叫而不能透过实例呼叫 add1则两者都可呼叫
这样理解应该没错吧?
24F:→ 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
25F:→ guaptpan: 所以如果针对原po的问题回答的话 07/20 00:46
26F:→ guaptpan: 有一个差别是不加@classmethod的method又不传入self就只 07/20 00:46
27F:→ guaptpan: 能在非实例实执行 07/20 00:46
28F:→ guaptpan: 建成实例就会出错 07/20 00:46
了解!!! 感谢各位陪我这个初学者讨论~
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:50:56
30F:→ s860134: 应该说你上面写的都没有把 instance 建出来 07/20 00:51
31F:→ s860134: 所以感觉怎麽都一样 07/20 00:51
所以如果用instance呼叫add2 就会因为多传了一个self参数所以无法执行 应该没错吧XD
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 00:54:58
32F:→ s860134: 你加个 c= Cal() 建立一个 instance 再试上面两个 method 07/20 00:54
33F:→ s860134: 第二个会出错,他会跟你说你丢了3个参数但是他只吃2个 07/20 00:54
34F:→ s860134: 对 instance 来说,第一个参数会默认放入自己 07/20 00:55
35F:→ s860134: 另外是 type 改变了 07/20 00:55
36F:→ s860134: 你在 ide 上面打 Cal.add2 会显示 "function Cal.add2 at 07/20 00:56
37F:→ s860134: c.add2 则会显示 bound method Cal.add2 07/20 00:57
恩恩终於搞懂差别在哪了QQ 谢谢s大!
※ 编辑: m06800825 (123.193.77.113), 07/20/2018 01:00:05
38F:→ s860134: python3 用了好一阵子现在才知道 unbound method 没了QQ 07/20 01:01