7

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)
Amit Tripathi
  • 7,003
  • 6
  • 32
  • 58
user1050619
  • 19,822
  • 85
  • 237
  • 413
  • 3
    you are getting an error because `log_decorator` doesn't take a function as an argument, **the function it returns does,** so at a minimum to understand where you are going wrong change it to `@log_decorator()` or remove the extra layer of function and just use `log_real_decorator` at global level, then you will get a more relevant error. – Tadhg McDonald-Jensen Dec 14 '17 at 18:42

1 Answers1

15

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.

Amit Tripathi
  • 7,003
  • 6
  • 32
  • 58