What is the difference between a function decorated with @staticmethod and one decorated with @classmethod?
Another consideration with respect to staticmethod vs classmethod comes up with inheritance. Say you have the following class:
class Foo(object):
@staticmethod
def bar():
return "In Foo"
And you then want to override bar()
in a child class:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
This works, but note that now the bar()
implementation in the child class (Foo2
) can no longer take advantage of anything specific to that class. For example, say Foo2
had a method called magic()
that you want to use in the Foo2
implementation of bar()
:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
@staticmethod
def magic():
return "Something useful you'd like to use in bar, but now can't"
The workaround here would be to call Foo2.magic()
in bar()
, but then you're repeating yourself (if the name of Foo2
changes, you'll have to remember to update that bar()
method).
To me, this is a slight violation of the open/closed principle, since a decision made in Foo
is impacting your ability to refactor common code in a derived class (ie it's less open to extension). If bar()
were a classmethod
we'd be fine:
class Foo(object):
@classmethod
def bar(cls):
return "In Foo"
class Foo2(Foo):
@classmethod
def bar(cls):
return "In Foo2 " + cls.magic()
@classmethod
def magic(cls):
return "MAGIC"
print Foo2().bar()
Gives: In Foo2 MAGIC