spencer
spencer

Reputation: 189

Should every method that doesn't use the self parameter be a static class?

I was just wondering, because occasionally I come across some code where I think they'd be fine as static methods but the coders didn't place the decorator for some methods. For other methods they're in place.

So... maybe they had something in mind when they did or didn't use the static method decorator? Is there any advantage to this approach? Or were they just being lazy by omitting the decorator?

Thanks.

Upvotes: 5

Views: 1553

Answers (1)

mgilson
mgilson

Reputation: 309929

Without seeing concrete code, it's pretty hard to give general guidelines. I will say that generally, staticmethod doesn't get a whole lot of love from the community. You can see this in a number of posts ... e.g.:

... we all know how limited static methods are. (They're basically an accident -- back in the Python 2.2 days when I was inventing new-style classes and descriptors, I meant to implement class methods but at first I didn't understand them and accidentally implemented static methods first. Then it was too late to remove them and only provide class methods.)

I've also worked places where the style guide said "NO STATIC METHODS", instead, prefer module level methods.


I mostly agree with the above advice. If you're going to use a static method, you should be prepared to defend why you need the method to be part of the class namespace rather than the module namespace. There are some defenses that may or may not make sense depending on the situation:

  1. You want to override the method in a subclass
    • This happens very rarely in my experience -- And frequently when it does happen, you really wanted a classmethod in the first place.
  2. You think that the method makes more sense semantically to be part of the class.

Ok, now lets talk about methods without self. Python3.x changed the behavior of methods. The following works in python3.x but not python2.x...

>>> class Foo(object):
...   def static():
...     return 'bar'
... 
>>> print(Foo.static())
bar

however, it won't work to call static from an instance. Instead, it'll give a pretty unhelpful error message:

>>> print(Foo().static())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: static() takes 0 positional arguments but 1 was given

I suppose if you had a python3.x only project and you really wanted to prevent a method from getting called on an instance, but wanted to call it on the class...1.

Otherwise, you should probably put a @staticmethod in there, consider whether the method would be better as a @classmethod or move the method to the module namespace. It'll increase the usability of that method. It'll also give more information to people reading the code so they can know how the method is meant to be called/used.

1I really can't think of a situation where you would want this ...

Upvotes: 4

Related Questions