Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python decorator as a staticmethod

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?

like image 983
wkz Avatar asked Jun 20 '11 13:06

wkz


People also ask

What is the purpose of Staticmethod in Python?

Static methods are used when we don't want subclasses of a class change/override a specific implementation of a method.

What is the difference between Staticmethod and Classmethod in Python?

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.

Should I use Staticmethod Python?

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.

What is the benefit of the @staticmethod decorator?

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.


1 Answers

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.

like image 156
Sven Marnach Avatar answered Sep 19 '22 22:09

Sven Marnach