如果我们想要和Java一样,在不实例化对象的情况下,使用类名.方法名()
完成方法调用,可以使用@staticmethod
装饰器将类的成员方法定义为静态方法,或者使用@classmethod
装饰器将类的成员方法定义属于为类的方法(严格来讲,方法应该是属于实例化之后对象的方法,因为方法在面向对象的概念里是行为的抽象)。
@staticmethod & @classmethod
代码语言:javascript复制class Math:
@staticmethod
def add(x, y): # 注意没有self参数
return x y
@classmethod
def minus(cls, x, y):
return x-y
@classmethod
def multiply(self, x, y):
return x*y
@classmethod
def divide(p, x, y):
return x / y
@classmethod
def mod_classmethod(x, y):
return x%y
@staticmethod
def mod_staticmethod(self, x, y): # 注意有self参数
return x%y
@staticmethod
def test_staticmethod(): # 注意没有任何参数
print("test")
@classmethod
def test_classmethod(): # 注意没有任何参数
print("test")
print(Math.add(10, 30))
print(Math.minus(10, 30))
print(Math.multiply(10, 30))
print(Math.divide(10, 30))
print(Math.mod_classmethod(10, 30))
print(Math.mod_staticmethod(10, 30))
print(Math.test_staticmethod())
print(Math.test_classmethod())
结果:
代码语言:javascript复制# 为了区分 每个结果之间一个空行
40
-20
300
0.3333333333333333
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-1672ad606091> in <module>
23 print(Math.multiply(10, 30))
24 print(Math.divide(10, 30))
---> 25 print(Math.mod_classmethod(10, 30))
26 print(Math.mod_staticmethod(10, 30))
TypeError: mod_classmethod() takes 2 positional arguments but 3 were given
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-29-a5d24c57cbaf> in <module>
24 print(Math.divide(10, 30))
25 # print(Math.mod_classmethod(10, 30))
---> 26 print(Math.mod_staticmethod(10, 30))
TypeError: mod_staticmethod() missing 1 required positional argument: 'y'
test
None
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-36-cd92235670d8> in <module>
8
9 print(Math.test_staticmethod())
---> 10 print(Math.test_classmethod())
TypeError: test_classmethod() takes 0 positional arguments but 1 was given
本例说明了@staicmethod
和@classmethod
的异同点以及self和cls的异同点:
- 都可以实现将方法定义为类的方法(静态方法默认就是类的方法)
@staticmethod
包装的方法不需要任何参数,包括self
@classmethod
包装的方法默认传递了cls
参数self
和cls
代表的本类实例,无实质区分,甚至它们占用的位置参数可以用任意合法参数名替换,不会出现异常
以上结论如果你有疑惑,可以去参考文献里找详细的说明,这里属于总结性的说明。
参考文献
浅谈python中的实例方法self、类方法cls和静态方法 python中的cls到底指的是什么,与self有什么区别? 飘逸的python - @staticmethod和@classmethod的作用与区别 @staticmethod和@classmethod的用法