How to use decorators in Python

Decorator is a function returning another function, it is applied as a function transformation using the @wrapper syntax. Common examples for decorators are classmethod() and staticmethod(). Lets understand decorators with some examples.

To understand decorators we will create two functions, one function will work as a decorator and other function will be decorated by decorator.

  • function execution_time will work as decorator
  • function decorated_func will be decorated with execution_time
  • Define execution_time and decorated_func

    
    def decorated_func():
        dl =[]
        for i in range(100):
            dl.append(i)
    
    
    def execution_time(func):
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            msg = f"time elapsed in executing func is { end - start}"
            return msg
        return wrapper
        

    As from the function definition we can see execution_time function calculates time taken by the decorated_func, lets use @ syntax to decorate the decorate_func

    
    import time
    
    def execution_time(func):
        def wrapper():
            start = time.time()
            func()
            end = time.time()
            msg = f"time elapsed in executing func is { end - start}"
            return msg
        return wrapper
    
    @execution_time
    def decorated_func():
        dl =[]
        for i in range(100):
            dl.append(i)
    
    elapsed_time = decorated_func()
    print(elapsed_time)
    
    
        

    Output

    
    time elapsed in executing func is 0.0010013580322265625
    
    

    Now, instead of hard coding "100" in range of decorated_func, use argument to provide different values, lets see how decorator would be changed to accommodate this.

    
    import time
    
    def execution_time(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            func(*args, **kwargs)
            end = time.time()
            msg = f"time elapsed in executing func is { end - start}"
            return msg
        return wrapper
    
    @execution_time
    def decorated_func(k):
        dl =[]
        for i in range(k):
            dl.append(i)
    
    elapsed_time = decorated_func(100000)
    print(elapsed_time)
    
    

    Output:

    
    time elapsed in executing func is 0.020013809204101562
    
    

    So with the use of *args and **kwargs we are able to pass argument to the decorated functions.

    Categories: Python