["python","decorator","static-methods","python-3.9"]
Python version <= 3.9: Calling class staticmethod within the class body?

When I attempt to use a static method from within the body of the class, and define the static method using the built-in staticmethod function as a decorator, like this: class Klass(object): @staticmethod # use as decorator def _stat_func(): return 42 _ANS = _stat_func() # call the staticmethod def method(self): ret = Klass._stat_func() + Klass._ANS return ret I get the following error: Traceback (most recent call last): File "call_staticmethod.py", line 1, in <module> class Klass(object): File "call_staticmethod.py", line 7, in Klass _ANS = _stat_func() TypeError: 'staticmethod' object is not callable I understand why this is happening (descriptor binding), and can work around it by manually converting _stat_func() into a staticmethod after its last use, like so: class Klass(object): def _stat_func(): return 42 _ANS = _stat_func() # use the non-staticmethod version _stat_func = staticmethod(_stat_func) # convert function to a static method def method(self): ret = Klass._stat_func() + Klass._ANS return ret So my question is: Are there cleaner or more "Pythonic" ways to accomplish this?
update for python version >= 3.10: staticmethod functions can be called from within class scope just fine (for more info see: python issue tracker, or "what's new", or here) for python version <= 3.9 continue reading staticmethod objects apparently have a __func__ attribute storing the original raw function (makes sense that they had to). So this will work: class Klass(object): @staticmethod # use as decorator def stat_func(): return 42 _ANS = stat_func.__func__() # call the staticmethod def method(self): ret = Klass.stat_func() return ret As an aside, though I suspected that a staticmethod object had some sort of attribute storing the original function, I had no idea of the specifics. In the spirit of teaching someone to fish rather than giving them a fish, this is what I did to investigate and find that out (a C&P from my Python session): >>> class Foo(object): ... @staticmethod ... def foo(): ... return 3 ... global z ... z = foo >>> z <staticmethod object at 0x0000000002E40558> >>> Foo.foo <function foo at 0x0000000002E3CBA8> >>> dir(z) ['__class__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] >>> z.__func__ <function foo at 0x0000000002E3CBA8> Similar sorts of digging in an interactive session (dir is very helpful) can often solve these sorts of question very quickly.