Intro to Python decorators

**Examples of functions

In Python, functions and classes are both objects:

def tell(msg):
  print(msg)

tell("Hello")
repeat = tell
repeat("Hello")

Functions can be passed as arguments to another function. Such function that take other functions as arguments are called higher order functions:

def inc(x):
  return x+1

def dec(x):
 return x-1 

def operate(func, x):
  result = func(x)
  return result

# run
operate(inc, 3) # returns 4
operate(dec, 3) # returns 2

Nested functions

def make_string(func):
  def add_char():
    str = func()
    str += 'a'  
    return str
  return add_char

def my_number():
  return "123456789_"

#Let's run the code
an_instance = make_string(my_number)
an_instance() #returns "123456789_a"

The function that is nested is said to be decorated. Generally, we decorate a function and assign it with the same name:

my_number = make_string(my_number)
my_number() #returns "123456789_a"

Uing @:

@make_string #function to be decorated
def my_number():
  return "123456789_"

which is equivalent to:

@make_string #function to be decorated
def my_number():
  return "123456789_"

my_number = make_string(my_number)