2

What is the pythonic way to call a static method from within the class?

class SomeClass:
    @staticmethod
    def do_something(x: int) -> int:
        return 2*x + 17

    def foo(self) -> None:
        print(self.do_something(52))      # <--- this one?
        print(SomeClass.do_something(52)) # <--- or that one?
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

2 Answers2

4

This depends entirely on your use case since in the context of subclassing, these two approaches do different things. Consider the following:

class OtherClass(SomeClass):
    @staticmethod
    def do_something(x: int) -> int:
        return 42

OtherClass().foo()

This will print 42 and 121 since self.do_something(52) uses the method resolution order while SomeClass.do_something(52) always refers to the same method (unless the name SomeClass got bound to a different object).

a_guest
  • 34,165
  • 12
  • 64
  • 118
0

I would argue that it is pythonic to call the staticmethod using

SomeClass.do_something(52)

From the source:

It can be called either on the class (e.g. C.f()) or on an instance (e.g. C().f()); the instance is ignored except for its class.

Even if one were to call it on an instance, it would still only infer the class from it and execute the function

x = 123
x.__class__
<class 'int'>
InsertCheesyLine
  • 1,112
  • 2
  • 11
  • 19
  • Can you provide the link to the quote? – OrenIshShalom May 31 '22 at 07:38
  • @OrenIshShalom I'm afraid that would involve digging around a bit, you can find more on it [here](https://stackoverflow.com/a/12718397/11323371) – InsertCheesyLine May 31 '22 at 07:41
  • "it would still only infer the class from it" That is an extremely important feature, since it means that subclassing allows to override staticmethods. Just because this isn't needed in a trivial case without inheritance doesn't mean it can – nor should – always be ignored. – MisterMiyagi May 31 '22 at 07:56
  • @MisterMiyagi while subclassing is viable, the question was about doing it *within* the class. – InsertCheesyLine May 31 '22 at 08:16
  • Doing it within the class is needed to allow subclassing it as well. It's the same as how calling `SomeClass.foo(self)` would be bad for subclassing. – MisterMiyagi May 31 '22 at 08:21