1

The names "staticmethod" and "classmethod" sound like they should something that can get called for a class, without needing an instance. On the other hand, methods defined in a class which are not classmethods or staticmethods sound intuitively like they should be something that can only be called for an instance.

But it seems the opposite of that intuition is true: code at the same level as the method definitions in a class cannot call staticmethod or classmethod functions but can call "instance" methods. For example:

class C1:
    def f1(*args):
        return "x"
    a1 = f1()  # works

    @staticmethod
    def f2(*args):
        return "y"
    a2 = f2()   # does NOT work

    @classmethod
    def f3(*args):
        return "z"
    a3 = f3()  # does NOT work

I do not really understand the rationale behind this.

One would assume that whatever is defined in the toplevel is part of the class itself, and that what comes later can make use of what comes before. One would assume that once all the code at the toplevel has been executed, that is what is known to the class "C1" and what will get inherited by all instances.

But apparently this is not the case. What exactly is the case, and more importantly, why has it been decided not to implement what would have been the intuitive way to do it?

Question 'staticmethod' object is not callable implies, that static methods (and class methods) are not accessible within the body of the class, but instead can be accessed using e.g. f2.__func__()

My question is not about this aspect of HOW it works, but WHY it works that way, which means that the use of the methods in the body is opposite to what one would expect given the semantics of instance methods, class methods and static methods. In other words: why does this design decision make sense?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
jpp1
  • 2,019
  • 3
  • 22
  • 43
  • 3
    You cannot call an instance method in a class body: You can call the function that will become a method once the class body has been executed. – L3viathan Sep 20 '19 at 13:19
  • Comparing `print(type(method_name))` in the class body vs `print(type(class_name.method_name))` outside the class body, `f1` doesn't change, but `f2` and `f3` do (`'staticmethod'` -> `'function'` and `'classmethod'` -> `'method'`, respectively). – wjandrea Sep 20 '19 at 13:48
  • 1
    I think you can find a very nice explanation about the case you are exposing on the following link: https://stackoverflow.com/questions/41921255/staticmethod-object-is-not-callable-switch-case – Miguel Sep 20 '19 at 14:20
  • 3
    Possible duplicate of ['staticmethod' object is not callable](https://stackoverflow.com/questions/41921255/staticmethod-object-is-not-callable-switch-case) – wjandrea Sep 20 '19 at 14:43
  • Note that your `f1` is not really an instance method—it has no `self`, and you’d have a really hard time producing an appropriate value for it from within the class statement if it did. (`f3` is similarly missing `cls`, but that doesn’t really matter here.) – Davis Herring Sep 25 '19 at 05:44

0 Answers0