what is decorator in python code example

Example 1: python function decorator

#Decorator are just function that take function as first
#parameter and return a function
def logging(f):
  def decorator_function(*args, **kwargs):
    print('executing '+f.__name__)
    return f(*args, **kwargs)
  return decorator_function
#Use it like this
@logging
def hello_world():
  print('Hello World')
#calling hello_world() prints out:
#executing hello_world
#Hello World

Example 2: decorator python

def our_decorator(func):
    def function_wrapper(x):
        print("Before calling " + func.__name__)
        func(x)
        print("After calling " + func.__name__)
    return function_wrapper

@our_decorator
def foo(x):
    print("Hi, foo has been called with " + str(x))

foo("Hi")

Example 3: python decorators

# decorators are user to decorate functions like what to do before/after calling the function
import time

def delay_decorator(function):
    def wrapper_function():
        print("-----------------------I am gonna greet you--------------------------")
        time.sleep(2)# waits for 2 seconds
        function()   # calls the function
        time.sleep(1)# waits for 1 sec
        print("------------------How do you feel about that greet?-------------------")
    return wrapper_function

@delay_decorator
def greet():
    print("Helllllloooooooooo")

greet()

Example 4: decorators in python

'pass function which we want to decorate in decorator callable object'
def our_decorator(func):  # func is function to be decorated by decorator
  
  def wrapper(x):       # x is parameter which is passed in func
    if x%2==0:
      return func(x)
    else:
      raise Exception("number should be even")
  return wrapper

@ our_decorator
def func(x):         # actual function 
  print(x,"is even")
func(2)
func(1)

' if you do not want to use @'
func=our_decorator(func)
func(2)

Example 5: python decorator

# Decorator with arguments
import functools

# First function takes the wanted number of repetition
def repeat(num_times):
    # Second function takes the function
    def decorator_repeat(func):
        # Third function, the wrapper executes the function the number of times wanted        
        # functools decorator to print the true name of the function passed instead of "wrapper"
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result= func(*args, **kwargs)
            return result
        return wrapper
    return decorator_repeat

# Our function using the decorator
@repeat(num_times= 3)
def greet(name):
    print(f"Hello {name}")

greet("thomas")

Example 6: python decorator

import functools

# A decorator is a Higher order function "_with_logging"
# It takes the function to be decorated as its argument
# In order to pass in some arbitrary arguments, it must be wrapped into
# another HOF (Higher order function) that will receive the inputs
def with_logging(level=logging.DEBUG, msg = None):
    def _with_logging(fn):
        # 'wraps' is a HOF that will give fn's name and docs to decorated_fn i.e. 
        #   decorated_fn.__name__ = fn.__name__
        #   help(decorated_fn) = help(fn)
        @functools.wraps(fn)
        def decorated_fn(*args, **kwargs):
            res = fn(*args, **kwargs)
            print("\n***************", f"\n{msg}", "\nExecuting with Args: ", *args, **kwargs)
            logging.log(level, res)
            return res
        return decorated_fn
    return _with_logging
  
# Used this way
@with_logging(level=logging.DEBUG, msg="Some awesome comment")
def hello_world(name):
  return f'Hello World {name}'
  
# Results after calling hello_world("John")
#
# ***************
# Some awesome comment
# Executing with Args: John
# Hello World John