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):<br>
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 better, as in cleaner or more "Pythonic", ways to accomplish this?
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.