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)
An unbound method is essentially a function with some trimmings. A 'bound method' is called that because the first argument (ie self ) is already set to a ; you can call b(10) and it works just the same way as if you had done a. fred(10) (this is actually necessary given how CPython operates).
Static methods can be bound to either a class or an instance of a class. Static methods serve mostly as utility methods or helper methods, since they can't access or modify a class's state. Static methods can access and modify the state of a class or an instance of a class.
A static method is precisely one which does not take self because it does not need to call other instance methods, or would do so via the class name.
Static method called with data So Cool! So the answer is yes, you can cal non-static methods from static methods. But only if you can pass in an instance as first parameter. So you either have to generate it from inside the static method (and in that case you are probably better off with a class method) or pass it in.
After the class is defined, foo
is 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 your b
and c
) 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.
class d(object):
def foo():
pass
d.foo = staticmethod(d.foo.im_func)
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:
d.foo = staticmethod(d.__dict__['foo'])
(It also avoids creating and discarding the method wrapper.)
You must pass the function, not the unbound method.
>>> class d:
... def foo():
... pass
...
>>> d.foo = staticmethod(d.foo.im_func)
>>> d.foo()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With