0

I recently started using PyCharm and it tells me whenever one of my methods can be static (whenever I don't use any member).

I was wondering if it is a good practice to make methods static whenever I can or not. I know it's a bad habit in other (compiled) languages but it feels that for Python it would actually be lighter. Usually these kind of corrections suggested by PyCharm are backed by a PEP number but there's none for this one.

TL;DR Should I declare my methods as static even when I don't need to use them statically?

lagagne
  • 25
  • 1
  • 1
  • 6
  • 2
    I'd suggest focusing on the conceptual model more than the code in making this decision. Is an operation conceptually specific to an individual object instance (even if not needing to interact with that instance as currently implemented), or something generic to the type of objects the class you're working with represents? Alternately, does the operation have utility to code that may not have access to an instance of your class? Treat this message from PyCharm as a reminder to think about your conceptual model, rather than a suggestion of a specific result. – Charles Duffy Feb 23 '17 at 18:20
  • This seems to be a matter of preference. At least for me. – Dschoni Feb 23 '17 at 18:22
  • 1
    ...btw, "bad habit in other (compiled) languages" is... not something I would agree is categorically true. – Charles Duffy Feb 23 '17 at 18:23
  • Does this help? http://stackoverflow.com/questions/68645/static-class-variables-in-python – Dschoni Feb 23 '17 at 18:24
  • Thanks, so I won't do it unless it's useful. – lagagne Feb 23 '17 at 18:32
  • @CharlesDuffy It's just something I heard and never really knew why but I tended to avoid static methods unless necessary because of it. – lagagne Feb 23 '17 at 18:34
  • 1
    @Dschoni I have seen this post before posting. It's more about things we "can" do than "should". – lagagne Feb 23 '17 at 18:35
  • I've seen Java implemented in idiomatic C style (very static, dealing with arrays of primitive types rather than objects) run circles performance-wise around Java implemented using native Java idioms (lots of objects built to follow a conceptual domain model). The right tool for the job depends on, well, the job -- performance requirements, maintainability requirements, usage models, the works. Thinking about these things and weighing tradeoffs is what software engineering is *about*; thus, one should be sure to *know* the tradeoffs, to be able to think about them clearly. – Charles Duffy Feb 23 '17 at 18:40
  • ...so, there are cases where a static method (or a plain-vanilla function) is the Right Thing for completely unambiguous reasons -- a factory, for example, where the user necessarily has no instance on-hand before its use. And then there are cases where it's *probably* the Right Thing, but there are other options -- a utility function that's providing an associated calculation that can be useful without an instance of the class on hand, for example, could be a static method, but it could just as easily be a function not associated with any class at all; the choice there is largely stylistic. – Charles Duffy Feb 23 '17 at 18:46
  • ...but to choose a *method* instead of either a standalone function or a static function, in the above-mentioned associated-calculation case, is a stylistic choice I would, personally, consider a bad one: It would mean you're writing code that is needlessly unamenable to reuse, since for no good reason it's being written in such a way as to not be callable without an instance object it has no practical need for. – Charles Duffy Feb 23 '17 at 18:46
  • @CharlesDuffy Thanks for the info. I think it was actually about Java that I heard I should avoid it (not using the implementation you're talking about obviously. I agree it's important to know the tradeoffs, hence my question. When I do more serious development in another language I'll get informed for that language too. I just came out of school so Python is the first language I actually "work" with. – lagagne Feb 23 '17 at 18:50
  • re: Java -- I brought up the above example very intentionally, to showcase why what's the reputed "best practice" for a given language from an idiomatic-design perspective isn't always necessarily the right choice when factors other than compliance with local idiom (and benefits directly drawn from same -- code reuse, &c) are factored in. – Charles Duffy Feb 23 '17 at 18:53
  • (also, what "static" means across compiled languages varies quite a lot; using C static functions wherever possible is *absolutely* a best practice, allowing the compiler a much freer hand in optimizing for performance). – Charles Duffy Feb 23 '17 at 18:54
  • Usually when I felt I shouldn't do a static methods but PyCharm told me to was when I need an object for this method to be useful, but I'm using it inside another method and passing relevant information as parameters instead of accessing members and checking my conditions again. – lagagne Feb 23 '17 at 18:56

1 Answers1

1

A method, a function attribute of a class, can be declared static if it cannot possibly use the first argument, the instance of a class. Defining a function with an unused parameter/bug is generally a bad idea. If the lack of use is a bug, because the argument should be used, then that should be fixed. If the lack of use is not a bug, then (in general), the parameter should be removed from the header.

What PyCharm should also suggest, if the non-use is not a bug, is removing the function from the class and the unused self parameter from the definition, so that it can be called without needing an irrelevant class instance. Python is not Java. Python used modules rather than classes as the default function container. Example:

def C:
    def fmeth(self, x):

def ffunc(x):
    return x * 3 + 2

print(C().fmeth(0), ffunc(0)

Except in some special cases, nothing is gained by requiring that the function be accessed through a C instance.

The Python stdlib makes almost no used of staticmethod(). Except for tests, there are only about 20 uses, and the ones I checked can be seen as special cases. Guido van Rossum has said that the addition of staticmethod along with classmethod was questionable and that it should not be used much.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
  • Oh nice, thank you. I wasn't thinking enough in modules. I'll just move it outside the class and avoid importing it then. – lagagne Feb 23 '17 at 19:40