Why does PyCharm propose to change method to static?

137,701

Solution 1

PyCharm "thinks" that you might have wanted to have a static method, but you forgot to declare it to be static (using the @staticmethod decorator).

PyCharm proposes this because the method does not use self in its body and hence does not actually change the class instance. Hence the method could be static, i.e. callable without passing a class instance or without even having created a class instance.

Solution 2

Agreed with @jolvi, @ArundasR, and others, the warning happens on a member function that doesn't use self.

If you're sure PyCharm is wrong, that the function should not be a @staticmethod, and if you value zero warnings, you can make this one go away two different ways:

Workaround #1

def bar(self):
    self.is_not_used()
    doing_something_without_self()

def is_not_used(self):
    pass

Workaround #2 [Thanks @DavidPärsson]

# noinspection PyMethodMayBeStatic
def bar(self):
    doing_something_without_self()

The application I had for this (the reason I could not use @staticmethod) was in making a table of handler functions for responding to a protocol subtype field. All handlers had to be the same form of course (static or nonstatic). But some didn't happen to do anything with the instance. If I made those static I'd get "TypeError: 'staticmethod' object is not callable".

In support of the OP's consternation, suggesting you add staticmethod whenever you can, goes against the principle that it's easier to make code less restrictive later, than to make it more -- making a method static makes it less restrictive now, in that you can call class.f() instead of instance.f().

Guesses as to why this warning exists:

  • It advertises staticmethod. It makes developers aware of something they may well have intended.
  • As @JohnWorrall's points out, it gets your attention when self was inadvertently left out of the function.
  • It's a cue to rethink the object model; maybe the function does not belong in this class at all.

Solution 3

I think that the reason for this warning is config in Pycharm. You can uncheck the selection Method may be static in Editor->Inspection

Solution 4

I agree with the answers given here (method does not use self and therefore could be decorated with @staticmethod).

I'd like to add that you maybe want to move the method to a top-level function instead of a static method inside a class. For details see this question and the accepted answer: python - should I use static methods or top-level functions

Moving the method to a top-level function will fix the PyCharm warning, too.

Solution 5

I can imagine following advantages of having a class method defined as static one:

  • you can call the method just using class name, no need to instantiate it.

remaining advantages are probably marginal if present at all:

  • might run a bit faster
  • save a bit of memory
Share:
137,701

Related videos on Youtube

zerkms
Author by

zerkms

Yet another software developer https://cv.zerkms.com/ #SOreadytohelp

Updated on March 26, 2022

Comments

  • zerkms
    zerkms over 2 years

    The new pycharm release (3.1.3 community edition) proposes to convert the methods that don't work with the current object's state to static.

    enter image description here

    What is the practical reason for that? Some kind of micro-performance(-or-memory)-optimization?

    • zerkms
      zerkms about 10 years
      @Wooble: there is return 1 as a single line implementation of the method. "More" doesn't contain anything useful
  • zerkms
    zerkms about 10 years
    Yep. But the thing is - I'm not using it as a static method. Otherwise it would already be static. So PyCharm advices to do it with no good reason (?). "remaining advantages are probably marginal if present at all" --- yep, exactly. But if it's the case - it's a silly advice from PyCharm
  • Jan Vlcinsky
    Jan Vlcinsky about 10 years
    @zerkms this is how it goes with some charming instances :-)
  • supersick
    supersick almost 9 years
    So many people have answered with this flavour response. I would add though, if you know it's definitely not going to be a static method, then include a "throw NotImplementedError" while you are there to be certain you don't use it without completing it.
  • zerkms
    zerkms almost 9 years
    "making a method static makes it less restrictive now" --- it does not at all. Eg: polymorphic methods
  • dhill
    dhill over 8 years
    I think the last point bears repeating: "why do you make it a method, when it's clearly a function?" Keep the stuff that really needs an instance separate from the structural stuff that deals with some aspect. You can then easily subdivide it into separate module.
  • Bob Stein
    Bob Stein over 8 years
    @dhill Rules are beautiful things until the day you think up a reasonable exception. I described one, a list of callbacks.
  • dhill
    dhill over 8 years
    @BobStein-VisiBone if they are not using instance variables, then why not use module for grouping? Sure sometimes a static method fits into the story, that's why it exists, but I thought this particular point from you was important.
  • zerkms
    zerkms about 8 years
    My question was why such an inspection even exists. I understand I can switch it off. Sorry, not an answer.
  • Jesuisme
    Jesuisme over 7 years
    I find this feature of PyCharm helpful and I strongly agree with the last point. Using non-static class methods that don't reference self is code smell.
  • jolvi
    jolvi over 7 years
    There might be cases where PyCharm's warning is unjustified in that we neither want a static method nor to change the state. On the other hand, if the method is not yet implemented, it seems always a good idea to raise a NotImplementedError.
  • David Pärsson
    David Pärsson about 7 years
    Adding # noinspection PyMethodMayBeStatic above the method or class suppresses the warning, and is in my opinion better than calling an empty method.
  • Bob Stein
    Bob Stein over 6 years
    Agreed @DavidPärsson, added to the answer as workaround #2. That's how I do it today. Keeping #1 because it's slightly less arcane. Readers can choose.
  • Amir Hossein Baghernezad
    Amir Hossein Baghernezad over 6 years
    Static methods are an enemy to building good software. They void many principles so the bit running faster is not the point (cause they run in ram so its fast in both cases) and as you know computers now have bunch of memory so that is not a problem anymore. Also note your first thought: That is a procedural behavior not an object oriented one.
  • Alfe
    Alfe over 5 years
    I have the case that my default implementation returns a constant, but my subclasses are allowed to return a value depending on self. In this case the warning is neglectable, and I mark it with # noinspection PyMethodMayBeStatic. It's a pitty that IntelliJ IDEA doesn't offer adding this disabling comment in the context menus for this warning.
  • maciek
    maciek over 5 years
    I suggest changing severity of this PyCharm inspection from "Warning" to "No highlighting, only fix" in PyCharm's preferences. (It's producing many false positives for me.)
  • Talha
    Talha over 5 years
    Just adding my thoughts, I am using python 3 and self is already removed, so why pycharm is still giving these warnings? My guess is Lint is still targetting version 2.x.
  • Suzana
    Suzana about 5 years
    Really helpful answer - maybe PyCharm should rename the warning to 'method may be static or top-level function'. When refactoring out a method, pycharm will create a top-level function and not a static method anyway, if self is not a parameter.
  • Junuxx
    Junuxx about 5 years
    @Talha: self is not removed in Python3 at all.
  • Talha
    Talha about 5 years
    Removed was not the right word to use there, it should be, "not necessary to write now".
  • Bob Stein
    Bob Stein about 5 years
    @Talha, I'm not understanding your point. I can't think of any way that self in Python 2 would not be necessary in Python 3. Can you give an example or link?
  • kasimir
    kasimir over 4 years
    @tlo +1 for mentioning the decorator. I have a class with a method that does not use self and therefore could be top-level, however, this does not feel logical when looking at what this method does - as top-level it would look more of a global method, while it is in fact a small helper method for instances created from that class. So to keep my code logically organised, the decorator is the perfect solution.
  • zerkms
    zerkms over 4 years
    It passes self so what?
  • Junyu Wu
    Junyu Wu over 4 years
    @zerkms '@staticmethod' doesn't pass 'self'
  • zerkms
    zerkms over 4 years
    I just cited you: "Python will pass self as the first argument... Pycharm knows it.". So what? Pycharm knows it, I know it. What's the reason to mark the method?
  • Junyu Wu
    Junyu Wu over 4 years
    @zerkms because Pycharm thinks your first method param may not be the "self". Normally ppl won't design a method param and never use it. Pycharm thinks you are creating a static method and didn't realize that the first param is not the "self", so it puts a warning by default. This confusion caused by the programing language design. I suggest you follow the programing design(even it seems not a good pattern), add "staticmethod", to avoid confusion. It's totally fine if you add a "self" then never use it if you prefer. What I say is just a different opion by understanding programing design.
  • zerkms
    zerkms over 3 years
    My question was rather about rationale behind this suggestion, not workarounds.
  • KalC
    KalC over 3 years
    Got that. Wondering if this can be a way to signal the interpreter that this is not a static method.
  • Mr. B.
    Mr. B. over 3 years
    Not the answer to the question but very useful, thanks!
  • rooby
    rooby over 2 years
    I strongly disagree with workaround #1. Don't add unneeded code just to appease your IDE warning, it just makes more of a mess of things. It is a warning, not an error, you can just ignore it. The warning is just to prompt you to check whether you should make it static in this case.
  • rooby
    rooby over 2 years
    I would advise against doing this. Why make your code messier and more confusing just to make a warning for a specific IDE go away? It's just a warning to get you to review it. You don't have to do what it says if it's not the best solution. The IDE doesn't always know what's best for your code.
  • Bob Stein
    Bob Stein over 2 years
    @rooby I agree with you workaround #2 is better. That's what I use. (I feel stronger about code readability. #1 is extremely readable.) I strongly disagree that "you can just ignore it" is a wise policy with warnings. My policy is to rigorously fix or work-around all warnings, on the strictest setting. It's been my experience they catch lots of bugs early.