How can you make a class method static after the class is defined? In other words, why does the third case fail?
>>> class b: ... @staticmethod ... def foo(): ... pass ... >>> b.foo() >>> class c: ... def foo(): ... pass ... foo = staticmethod( foo ) ... >>> c.foo() >>> class d: ... def foo(): ... pass ... >>> d.foo = staticmethod( d.foo ) >>> d.foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unbound method foo() must be called with d instance as first argument (got nothing instead)
After the class is defined,
foois an unbound method object (a wrapper that ties the function to the class), not a function. The wrapper’s going to try to pass an instance of the class (self) to the function as the first argument and so it complains that you haven’t given it one.staticmethod()should really be used only with functions. While the class is still being defined (as in yourbandc)foo()is still a function, as the method wrapper is applied when the class definition is complete.It’s possible to extract the function from the unbound method object, apply
staticmethod(), and assign it back to the class.In Python 3, there are no unbound instance methods (methods stored on classes are plain functions). So your original code would actually work fine on Python 3.
A way that works on both Python 2 and Python 3 is:
(It also avoids creating and discarding the method wrapper.)