[Answered ]-Decorator to invoke instance method

2👍

I think this does what you want:

def validate_input(validation_fn_name):
    def validation_decorator(func):
        def validate_input_action(self, *args):
            error = getattr(self, validation_fn_name)(*args)
            if error is not None:
                raise error
            else:
                arglist = [self] + list(args)
                return func(*arglist)
        return validate_input_action
    return validation_decorator

class Foo(object):

    def validate_length(self, arg1):
        if len(arg1) < 3:
            return ValueError('%r is too short' % arg1)

    @validate_input('validate_length')
    def bar(self, arg1):
        print "Arg1 is %r" % arg1


if __name__ == "__main__":
    f = Foo()
    f.bar('hello')
    f.bar('')

Output is:

Arg1 is 'hello'
Traceback (most recent call last):
  File "validator.py", line 27, in <module>
    f.bar('')
  File "validator.py", line 6, in validate_input_action
    raise error
ValueError: '' is too short

Updated answer

The error (NameError: name 'Dummy' is not defined) occurs because the Dummy class is not defined yet when the validate_input decorator gets Dummy as an argument. I guess this could have been implemented differently, but for now that’s the way Python works. The easiest solution that I see is to stick to using getattr, which will work because it looks up the method at run time.

Leave a comment