I just can\'t see why do we need to use @staticmethod. Let\'s start with an exmaple.
class test1:
def __init__(self,value):
self.value=value
I will add something other answers didn't mention. It's not only a matter of modularity, of putting something next to other logically related parts. It's also that the method could be non-static at other point of the hierarchy (i.e. in a subclass or superclass) and thus participate in polymorphism (type based dispatching). So if you put that function outside the class you will be precluding subclasses from effectively overriding it. Now, say you realize you don't need self
in function C.f
of class C
, you have three two options:
Put it outside the class. But we just decided against this.
Do nothing new: while unused, still keep the self
parameter.
Declare you are not using the self
parameter, while still letting other C
methods to call f
as self.f
, which is required if you wish to keep open the possibility of further overrides of f
that do depend on some instance state.
Option 2 demands less conceptual baggage (you already have to know about self
and methods-as-bound-functions, because it's the more general case). But you still may prefer to be explicit about self
not being using (and the interpreter could even reward you with some optimization, not having to partially apply a function to self
). In that case, you pick option 3 and add @staticmethod
on top of your function.
The reason to use staticmethod
is if you have something that could be written as a standalone function (not part of any class), but you want to keep it within the class because it's somehow semantically related to the class. (For instance, it could be a function that doesn't require any information from the class, but whose behavior is specific to the class, so that subclasses might want to override it.) In many cases, it could make just as much sense to write something as a standalone function instead of a staticmethod.
Your example isn't really the same. A key difference is that, even though you don't use self
, you still need an instance to call static_add_one
--- you can't call it directly on the class with test2.static_add_one(1)
. So there is a genuine difference in bejavior there. The most serious "rival" to a staticmethod isn't a regular method that ignores self
, but a standalone function.
Today I suddenly find a benefit of using @staticmethod
.
If you created a staticmethod within a class, you don't need to create an instance of the class before using the staticmethod.
For example,
class File1:
def __init__(self, path):
out=self.parse(path)
def parse(self, path):
..parsing works..
return x
class File2:
def __init__(self, path):
out=self.parse(path)
@staticmethod
def parse(path):
..parsing works..
return x
if __name__=='__main__':
path='abc.txt'
File1.parse(path) #TypeError: unbound method parse() ....
File2.parse(path) #Goal!!!!!!!!!!!!!!!!!!!!
Since the method parse
is strongly related to the classes File1
and File2
, it is more natural to put it inside the class. However, sometimes this parse
method may also be used in other classes under some circumstances. If you want to do so using File1
, you must create an instance of File1
before calling the method parse
. While using staticmethod in the class File2
, you may directly call the method by using the syntax File2.parse
.
This makes your works more convenient and natural.
Use @staticmethod
for methods that don't need to operate on a specific object, but that you still want located in the scope of the class (as opposed to module scope).
Your example in test2.static_add_one
wastes its time passing an unused self
parameter, but otherwise works the same as test1.static_add_one
. Note that this extraneous parameter can't be optimized away.
One example I can think of is in a Django project I have, where a model class represents a database table, and an object of that class represents a record. There are some functions used by the class that are stand-alone and do not need an object to operate on, for example a function that converts a title into a "slug", which is a representation of the title that follows the character set limits imposed by URL syntax. The function that converts a title to a slug is declared as a staticmethod
precisely to strongly associate it with the class that uses it.