2013-04-23 130 views
15

我知道他们做了什么,我见过很多这两个例子,但我还没有找到一个例子,我不得不使用classmethod而不是用staticmethod代替它。为什么使用classmethod而不是staticmethod?

我见过的classmethod最常见的例子是用于创建新实例的类本身的,像这样的(很简单的例子,有没有使用ATM的方法,但你的想法。):

class Foo: 
    @classmethod 
    def create_new(cls): 
     return cls() 

当调用foo = Foo.create_new()时,将返回一个新的Foo实例。 现在为什么不能我只是用这个代替:

class Foo: 
    @staticmethod 
    def create_new(): 
     return Foo() 

它不完全一样的,为什么要我曾经使用classmethodstaticmethod

+7

@KevinBrydon对那个页面上的OP问题没有*答案*,但它可能在那里的注释中。我不知道是否有足够的理由来解决这个问题 – jamylak 2013-04-23 14:41:59

+1

这个问题不是链接问题的重复。链接问题的答案没有说明为什么要使用静态方法的类方法,反之亦然。 – spacetyper 2017-03-14 16:34:38

回答

17

有你的榜样差别不大,但假设您创建的Foo一个子类,并呼吁子类中的方法create_new ...

class Bar(Foo): 
    pass 

obj = Bar.create_new() 

...那么这个基类会引起新的Bar对象要创建...

class Foo: 
    @classmethod 
    def create_new(cls): 
     return cls() 

...而这个基类会导致创建一个新的Foo对象...

class Foo: 
    @staticmethod 
    def create_new(): 
     return Foo() 

...所以选择取决于你想要的行为。

+0

根本没有想到亚类,我的坏!感谢您的快速回答:)我会尽快接受。 – 2013-04-23 14:43:36

5

是的,这两个班级也会这样做。

不过,现在想象类的子类型:

class Bar (Foo): 
    pass 

现在呼吁Bar.create_new做不同的东西。对于静态方法,您会得到一个Foo。对于类方法,您会得到一个Bar

所以重要的区别是类方法获取作为参数传递的类型。

4

docs,类方法接收它的类作为隐式参数,而静态方法不知道它们所在的类。

这对于您想要用子类中的不同行为覆盖的继承静态方法的情况很有用。