python classmethod staticmethod

有两点不同

1. class method 会自动将当前class作为参数传入,但我觉得这并不能让它和 static method 产生差异,因为你完全可以这样写:

class F():
@staticmethod
def sm(cls):
print(cls)

@classmethod
def cm(cls):
print(cls)

F.sm(S) # <class '__main__.F'>
F.cm() # <class '__main__.F'>

一般这里会说classmethod可以防止硬编码,我觉得比较牵强,因为你调用的时候实际上已经需要指定调用class了,这里无非是多传了一个参数,看起来不太优雅,不过也可以通过其他方式解决,这样一来,classmethod在某些场景下确实能一定程度使得代码更美观简洁

2. 继承的差别才是我觉得classmethod的优势所在

class F():
@staticmethod
def sm():
print(F())

@classmethod
def cm(cls):
print(cls())

class S(F):
...

S.sm() # <__main__.F object at 0x00000290C6935120>
S.cm() # <__main__.S object at 0x00000290C6935120>

注意到,static method 创建的是父类对象,而class method 创建的是子类对象,所以classmethod的一个典型的应用场景就是创建当前类的对象

class MyClass:
@classmethod
def create_instance(cls, *args, **kwargs):
   # do some check before instance be created
return cls(*args, **kwargs)

如此一来,不管该类如何继承,都可以直接通过 XXX.create_instance() 来创建对应的对象

当然,如果硬要说的话,也可以给staticmethod添加一个cls的参数,这样的话又回到了第1点。

总结来说,看上去区别好像确实不大,用起来好像互相替换着用也能得到相同的效果,但是我觉得,这可能就像list和queue一样,很多场景下区别确实不大,但是就是因为存在的那一点区别,就能解决某个场景下的一个痛点。存在即合理

参考:https://stackoverflow.com/questions/75379715/python-creating-a-class-instance-via-static-method-vs-class-method

Leave a Comment