I'm trying to write a python class which uses a decorator function that needs information of the instance state. This is working as intended, but if I explicitly make the decorator a staticmetod, I get the following error:
Traceback (most recent call last): File "tford.py", line 1, in <module> class TFord(object): File "tford.py", line 14, in TFord @ensure_black TypeError: 'staticmethod' object is not callable
Why?
Here is the code:
class TFord(object): def __init__(self, color): self.color = color @staticmethod def ensure_black(func): def _aux(self, *args, **kwargs): if self.color == 'black': return func(*args, **kwargs) else: return None return _aux @ensure_black def get(): return 'Here is your shiny new T-Ford' if __name__ == '__main__': ford_red = TFord('red') ford_black = TFord('black') print ford_red.get() print ford_black.get()
And if I just remove the line @staticmethod
, everything works, but I do not understand why. Shouldn't it need self
as a first argument?
Static methods are used when we don't want subclasses of a class change/override a specific implementation of a method.
The static method does not take any specific parameter. Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class.
staticmethods can be used when the code that belongs to a class doesn't use the object itself at all. Python doesn't have to instantiate a bound method for each object we instantiate. Bound methods are objects too, and creating them has a cost. Having a static method avoids that.
This decorator exists so you can create class methods that are passed the actual class object within the function call, much like self is passed to any other ordinary instance method in a class. This follows the static factory pattern very well, encapsulating the parsing logic inside of the method itself.
This is not how staticmethod
is supposed to be used. staticmethod
objects are descriptors that return the wrapped object, so they only work when accessed as classname.staticmethodname
. Example
class A(object): @staticmethod def f(): pass print A.f print A.__dict__["f"]
prints
<function f at 0x8af45dc> <staticmethod object at 0x8aa6a94>
Inside the scope of A
, you would always get the latter object, which is not callable.
I'd strongly recommend to move the decorator to the module scope -- it does not seem to belong inside the class. If you want to keep it inside the class, don't make it a staticmethod
, but rather simply del
it at the end of the class body -- it's not meant to be used from outside the class in this case.
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