Decorate class that has no self in method signature in Python
Question: I am trying to apply decorator dynamically to classes. It works if I have a
class method including self in method signature.

**Working example:**

    
    
    from functools import wraps
    
    def debug(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('awesome')
            f = func(*args, **kwargs)
            return f
        return wrapper
    
    def debugclass(cls):
        # cls is a class
        for key, val in vars(cls).items():
            if callable(val):
                setattr(cls, key, debug(val))
        return cls
    
    class Dude:
        def test(self):
        #def test(): # this does not work
            pass
    
    debugclass(Dude)
    dude = Dude()
    dude.test()
    

**How could I change Dude class method signature so that it would work without
self being part of signature?**

    
    
    class Dude:
        def test(): # without self
            pass
    debugclass(Dude)
    dude = Dude()
    dude.test()
    

**Getting error:**

    
    
    Traceback (most recent call last):
    File "withoutself.py", line 33, in <module>
    dude.test()
    File "withoutself.py", line 7, in wrapper
    f = func(*args, **kwargs)
    TypeError: test() takes no arguments (1 given)
    


Answer: For your `test()` method to be callable without a `self` or `cls` parameter
you need to make it a `staticmethod`.

    
    
    class Dude:
        @staticmethod
        def test():
            pass
    

Then you also need to update `debugclass` to wrap `staticmethod` objects as
they aren't callables. Unfortunately you'll need a different way to wrap the
staticmethod objects:

    
    
    def debugclass(cls):
        # cls is a class
        for key, val in vars(cls).items():
            if callable(val):
                setattr(cls, key, debug(val))
            elif isinstance(val, staticmethod):
                setattr(cls, key, staticmethod(debug(val.__func__)))
        return cls
    
    >>> class Dude:
        def test(self):
            pass
        @staticmethod
        def test1():
            pass
    
    
    >>> debugclass(Dude)
    <class __main__.Dude at 0x7ff731842f58>
    >>> Dude().test()
    awesome
    >>> Dude.test1()
    awesome
    

