Reputation: 1971
Functions in a python class can be either instance methods, class methods or static methods.
The former is characterised by the self
as its first (implicit) argument, acts directly on the instance of the class, and does not require any decorators to be treated as such.
The other two, however, need decorators @classmethod
and @staticmethod
before the name of the method - this is why I refer to the instance method as the "default" one, i.e. the one for which a wrapper is not needed.
My question is:
suppose I am in a class, and I am breaking up my calculation into several functions for readibility. Only one of these methods will need access to the self.something
variables that I share instance-wise, but most of the others do not need to know about the class they belong to - they are just there for "housekeeping".
Should make these functions (the ones that do not need any self.something
knowledge) all @staticmethod
?
Doing so would require a decorator and hence an extra step.
It would be easier (not requiring the extra step of using a decotrator) for every method to just be an instance method, thus inheritig a lot of potential but also waisting it since it is not needed for the scope of the functions in question.
Why is the instance method the "default"?
Why not have every method a static method by default, and give it the extra functionality associated with being a instance method with a wrapper?
Upvotes: 0
Views: 1416
Reputation: 155428
The reason to default to instance methods is because that's usually what you want when you're doing object oriented programming. I can't think of a single language that claims to support OOP and has methods default to anything but instance methods. Classes are templates for "data with behaviors", so the default is to make methods that provide behaviors to each instantiation of the class. If you just want a collection of functions, you can just define them at the top level of a module and save the unnecessary class after all.
In general, @staticmethod
is used to mean "I know this isn't a behavior of the class or its instances, but it helps implement the real behaviors and isn't very useful outside the class, so I'll namespace it inside it." If the features are useful outside the class, you'd just make it a plain top-level function rather putting it inside the class at all. It is advantageous to use @staticmethod
where appropriate; it's a little faster to call than an instance method, so if you don't need the instance, @staticmethod
will speed up your code a bit (note: This may not be true in 3.7+, where they added an optimization to avoid the creation of bound methods, which may speed up instance/class methods).
@classmethod
basically has two use cases:
cls
it receives is the actual subclass, if applicable, not just the class it was defined in)@staticmethod
when the method needs to call other static methods and you'd rather not have to refer to the class by name over and overPoint is, @staticmethod
is mostly for when you're opting out of OOP, and @classmethod
s are for niche use cases; instance methods are just more useful, so they're the default. Beyond that, as a historical note, static and class methods were introduced later, so making them the default would have broken all existing Python code, for no real benefit.
The main reason to use @staticmethod
over instance methods with an ignored self
(when self
isn't needed) is that it will continue to work when called on the class itself, not just on instances of the class; if you tried to call MyClass.notreallystatic()
, it would die for lack of a self
, while MyClass.actuallystatic()
would work.
Upvotes: 2