Class method decorator with self arguments? Class method decorator with self arguments? python python

Class method decorator with self arguments?


Yes. Instead of passing in the instance attribute at class definition time, check it at runtime:

def check_authorization(f):    def wrapper(*args):        print args[0].url        return f(*args)    return wrapperclass Client(object):    def __init__(self, url):        self.url = url    @check_authorization    def get(self):        print 'get'>>> Client('http://www.google.com').get()http://www.google.comget

The decorator intercepts the method arguments; the first argument is the instance, so it reads the attribute off of that. You can pass in the attribute name as a string to the decorator and use getattr if you don't want to hardcode the attribute name:

def check_authorization(attribute):    def _check_authorization(f):        def wrapper(self, *args):            print getattr(self, attribute)            return f(self, *args)        return wrapper    return _check_authorization


A more concise example might be as follows:

#/usr/bin/env python3from functools import wrapsdef wrapper(method):    @wraps(method)    def _impl(self, *method_args, **method_kwargs):        method_output = method(self, *method_args, **method_kwargs)        return method_output + "!"    return _implclass Foo:    @wrapper    def bar(self, word):        return wordf = Foo()result = f.bar("kitty")print(result)

Which will print:

kitty!


from re import searchfrom functools import wrapsdef is_match(_lambda, pattern):    def wrapper(f):        @wraps(f)        def wrapped(self, *f_args, **f_kwargs):            if callable(_lambda) and search(pattern, (_lambda(self) or '')):                 f(self, *f_args, **f_kwargs)        return wrapped    return wrapperclass MyTest(object):    def __init__(self):        self.name = 'foo'        self.surname = 'bar'    @is_match(lambda x: x.name, 'foo')    @is_match(lambda x: x.surname, 'foo')    def my_rule(self):        print 'my_rule : ok'    @is_match(lambda x: x.name, 'foo')    @is_match(lambda x: x.surname, 'bar')    def my_rule2(self):        print 'my_rule2 : ok'test = MyTest()test.my_rule()test.my_rule2()

ouput: my_rule2 : ok