Search code examples
pythondecorator

Decorator for both class methods and functions


I have a decorator

def deco(func):
    def inner(params):
        #< DO STUFF WITH func >
    return inner

And a base class

class GenericClass:
    def __init__(self,value):
        self.value = value
    def method(self,params):
        print 'NOT IMPLEMENTED YET'
    def other_method(self):
        print 'GOOD TO GO'

I would like to be able to decorate the "method" method on classes which are child of GenericClass, for exemple to check input/output or handle exceptions (the method "method" will be overrided)

what I want to do is something like...

class ChildClass(GenericClass):
    @deco
    def method(self,params):
        #< NEW METHOD >

I am not an expert python developper and all the doc at that level is quite confusing (i.e. metaclasses, subtleties in decorators, __call__ method etc etc) and I didn't found the solution on SO.


Solution

  • Got it. You are basically asking how to write a decorator which can be applied to both functions and methods. It's possible:

    def deco(func):
        def inner(*args):
            print('DECORATED: args={}'.format(args))
            func(*args)
        return inner
    
    class Class:
        @deco
        def method(self, param): print('PARAM is {}'.format(param))
    
    @deco
    def func(a, b, c): print('{} {} {}'.format(a, b, c))
    
    Class().method('X')
    
    func(1, 2, 3)
    

    OUTPUT:

    DECORATED: args=(<__main__.Class instance at 0x7f740c6297a0>, 'X')
    PARAM is X
    DECORATED: args=(1, 2, 3)
    1 2 3
    

    P.S.

    One year later I found one useful post (which was asked 8 years ago) here: Using the same decorator (with arguments) with functions and methods. The approach described there will be useful if you are care of actual parameters of the decorated function.