romulomadu
romulomadu

Reputation: 657

Understanding functions wrappers in python's decorator

I have these two examples of python decorators implementation. I'd like to know what is the difference between them regarding function wrapper implementation. They work as the same way? There is any context difference? What is the pythonic way to do a function wrapper?

Example 1

from functools import wraps

def retry(times=3, waiting_time=30):
    '''
    Decorator to retry any functions 'times' times.

    Parameters
    ----------    
    times: int
        Number of times to retry to execute
    waiting_time: int
        Number of times to wait between retries

    '''
    def retry_decorator(func):
        # My doubt is here.
        @wraps(func)
        def retried_function(*args, **kwargs):
            for i in range(times):
                try:                           
                    return func(*args, **kwargs)
                except Exception as err:
                    print(f'Try nº {i+1}')
                    sleep(waiting_time)           

            func(*args, **kwargs)

        return retried_function

    return retry_decorator

Example 2

def exception(logger):
    '''
    Decorator that wraps the passed function and logs 
    exceptions when it occurs.

    Parameters
    ----------
    logger : logging object
        Object to use to log exceptions

    ''' 
    def decorator(func):
        # Here the function wrapper is different from example 1     
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                # log the exception
                err = "There was an exception in "
                err += func.__name__
                logger.exception(err) 
                # re-raise the exception
                raise
        return wrapper
    return decorator

Upvotes: 0

Views: 744

Answers (1)

Anis
Anis

Reputation: 3094

First of all, we are looking at something a little bit more sophisticated than a decorator. A decorator is a function that takes a function as input and returns a function. Here, the top functions return decorators. So they are actually also decorators in the sense above, even though what is usually called the decorator is the first inner function. This definition scheme is often useful to create parametric decorators.

With that out of the way, it seems you are specifically asking about functools.wraps. If so, I can only urge you to take a look at the doc https://docs.python.org/2/library/functools.html.

Basically, it used to make the function returned by the decorator look the same as the decorated function i.e.: have the same name, docstrings, etc...

Upvotes: 1

Related Questions