Decorators
Function basics
A function in Python is a named block of reusable code that performs a specific task. It consists of two main parts: the function definition and the function call.
Definition
The function definition is where you define the name* of the function, specify any input parameters it requires, and write the instructions or code that will be executed when the function is called. It serves as a blueprint for the function’s behavior.
Example of a function defnition:
[12]:
def add(x,y):
sum = x + y
return sum
note: functions in python are defined by using the keyworddef
The name of the function is actually, if you want to be totally correct, a variable, of the name add, that points at a function stored in memory.
So if we print out add like we would do with any other variable, we get its value:
[13]:
add
[13]:
<function __main__.add(x, y)>
Call
The function call, on the other hand, is when you actually invoke or execute the function. You use the function’s name followed by parentheses, and you can pass any required input values or arguments inside the parentheses. When a function is called, the code within its definition is executed.
[6]:
add(2,3)
[6]:
5
Return
Functions in python are always returning something. Either what you specifically write what it should return or it returns the value of None.
Example:
[ ]:
def add(x,y):
sum = a + b
return sum # this is what is return when calling the function
[5]:
def add(x,y):
print(a + b)
# in this case there is an invisible 'return None'
So the function above is actually looking like this.
[6]:
def add(x,y):
print(a + b)
return None
Return value
the return value can be stored in a variable
[7]:
sum = add(4, 5)
It is legal, and sometimes usefull as you will se later, to store the return value in a variable of any name, including add
[8]:
add = add(4, 5)
After this line of code is executed add is no longer a variable holding a function, it is a variable containing a number
[9]:
add
[9]:
9
First class functions
In python functions are first class functions, meanning that they can take other functions as parameters and they can return functions.
[17]:
def my_function(x):
# execute
x()
# or return
return x
[18]:
def greet():
return 'Hello'
[19]:
x = my_function(greet)
[20]:
x()
[20]:
'Hello'
Inner functions
[3]:
def foo():
# define
def inner():
return 'Inner msg'
# execute
print(inner())
foo()
Inner msg
I do not have access to the inner function from outside
[4]:
# inner()
# foo.inner()
# foo().inner()
# foo(inner())
But i can return the inner function and use it out side
[1]:
def foo():
def inner():
return 'Hello inner xxx'
return inner
i = foo()
i()
[1]:
'Hello inner xxx'
Simple Decorators
Version 1
[5]:
def deco(func):
def inner():
print('Hello from inner function')
return inner
[6]:
def greet():
print('Hello from greet function')
[7]:
greet = deco(greet)
greet()
Hello from inner function
Version 2
[5]:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func() # print(Hello)
print("Something is happening after the function is called.")
return wrapper
def greet():
print('Hello')
greet = my_decorator(greet)
greet()
## The 2 last lines of code could also have been written like this:
# wrapper = my_decorator(greet)
# wrapper()
Something is happening before the function is called.
Hello
Something is happening after the function is called.
Syntactic Sugar!
[6]:
@my_decorator
def greet():
print("Hello")
greet()
Something is happening before the function is called.
Hello
Something is happening after the function is called.
Decorating Functions With Arguments
[32]:
@my_decorator
def greet(name):
print(f'Hello {name}')
greet('Clais')
Something is happening before the function is called.
Hello Clais
Something is happening after the function is called.
[31]:
def my_decorator(func):
def wrapper(*args):
print("Something is happening before the function is called.")
func(*args) # print(Hello)
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def greet(name):
print(f'Hello {name}')
greet('Fin')
Something is happening before the function is called.
Hello Fin
Something is happening after the function is called.
Returning Values From Decorated Functions
[35]:
def my_decorator(func):
def wrapper(*args):
x = 'From wrapper before: '
x += func(*args) # return Hello name
x += ' : after from wrapper'
return x
return wrapper
@my_decorator
def greet(name):
return f'Hello {name}'
greet('Clais kjshhgfgkjshsfdkj')
[35]:
'From wrapper before: Hello Clais kjshhgfgkjshsfdkj : after from wrapper'
[ ]: