#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    100
    Rep Power
    2

    Post May someone explain this decorator code to me?


    The code has been taken from Learning Python 4th Edition by Mark Lutz
    Code:
    class tracer:
        def __init__(self, func):
            self.calls = 0
            self.func = func
        def __call__(self, *args):
            self.calls += 1
            print('call %s to %s' % (self.calls, self.func.__name__))
    
    
    @tracer
    def spam(a, b, c):
        print(a + b + c)
        
    spam(1, 2, 3)
    Also, when I ran this code, it doesn't print the sum, but in the book it's shown that it does!
    Any help with the explanation on how this code works?
    I know that @tracer above the spam function implies:

    spam = tracer(spam)

    and when we call spam, we get:

    tracer(spam)(1, 2, 3)
    Still, where does the 1,2,3 args go? And how does spam....I don't know. If I were asked to write a code using decorator, I wouldn't have been able to do it. So, any help describing what's happening in detail?

    Thanks, in advance.
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,837
    Rep Power
    480
    The decorator as a class with __call__ method is quite easy to read.

    Yes, it's messed up. __call__ doesn't bother to call the function! Try it like this:
    Code:
    class tracer:
        def __init__(self, func):
            self.calls = 0
            self.func = func
        def __call__(self, *args,**kwargs):
            self.calls += 1
            print('call %s to %s' % (self.calls, self.func.__name__))
            return self.func(*args,**kwargs)  ####### insertion!
    
    
    @tracer
    def spam(a, b, c):
        print(a + b + c)
        
    spam(1, 2, 3)
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo