Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python passing self to the decorator

I'm trying to pass the self object to my decorator to access its contents but get the following error:

def log_decorator():
    def log_real_decorator(f):
        @wraps(f)
        def wrapper(self,*args, **kw):      
            print "I am the decorator, I know that self is", self, "and I can do whatever I want with it!"
            print "I also got other args:", args, kw           
            f(*args, **kw)

        return wrapper        
    return log_real_decorator    

class Foo(object):
    @log_decorator

    def meth(self):
        print "I am the method, my self is", self


f = Foo()        
f.meth()

Error:-

TypeError: log_decorator() takes no arguments (1 given)
like image 857
user1050619 Avatar asked Dec 14 '17 18:12

user1050619


1 Answers

This is how you do it:

def log_real_decorator(f):
    @wraps(f)
    def wrapper(self, *args, **kw):      
        print "I am the decorator, I know that self is", self, "and I can do whatever I want with it!"
        print "I also got other args:", args, kw           
        f(self, *args, **kw)
        # ^ pass on self here

    return wrapper

Simply pass on self.

Or

If you want to create a generic decorator that can both be used for class and methods you can simply do this:

def log_real_decorator(f):
    @wraps(f)
    def wrapper(*args, **kw):
        # Do something here
        f(*args, **kw)

    return wrapper

Also, the decorator that you have created is used when you need to pass some parameters to the decorator(like @log_real_decorator(some_param=1). In your case, you don't need that, instead what you should do is create a decorator with two nested functions as I have done above and call it as @log_real_decorator.

like image 190
Amit Tripathi Avatar answered Oct 31 '22 13:10

Amit Tripathi