SIMPLE DECORATOR SYNTAX
1- Define a decorator
def decorator_function(function):
def wrapper_function():
# Do something before the function
function()
# Do something after the function
return wrapper_function
Python Decorator Function (4 lines of code)
1- Create a normal function.
2- Input is another normal function, the function in this case doesn't have parentheses ().
3- Inside the decorator_function, create a wrapper_function
The wrapper_function() will trigger the actual input "function()" that was passed into the decorator_function().
4- Return the wrapper_function without parentheses ().
Key takeaways:
+ Decorator function is just a function that wraps another function,
+ And GIVE that function some ADDITIONAL FUNCTIONALITY
2.1 - Using a decorator function by @ sign -> RECOMMENDED way.
@decorator_function #this line will trigger the decorator function for a_normal_function
def a_normal_function():
pass
2.2 - Using a decorator function by input function -> NOT RECOMMENDED way.
decorated_func = decorator_function(a_normal_function)
decorated_func() # remember to add parentheses ()
EXAMPLES
Requirements:
- All functions should be delayed by 5 seconds.
- Avoid adding
time.sleep(5)
to each function. - Add
time.sleep(5)
once.
Implementation:
We can modify delay_decorator to delay the execution of the wrapped function by 5 seconds.
import time
def delay_decorator(function):
def wrapper_function():
time.sleep(5) # wait 5 seconds before executing the next function
function()
return wrapper_function
@delay_decorator
def say_hello():
print("Hello!")
@delay_decorator
def say_bye():
print("GoodBye!")
def say_greeting():
print("How are you?")
Now we will define a main_flow:
def main_flow():
say_hello() # no delay because we don't add @delay_decorator to it
say_greeting() # delay 5s before executing greeting
say_bye() # delay 5s before executing GoodBye
main_flow()
Result:
Hello!
wait 5s
How are you?
wait 5s
GoodBye!
ADVANCE DECORATOR SYNTAX
Class and Adv Python Decorator
1. Requirements:
Users have to provide their name, and is_logged_in = True
Create a decorator to ensure users log in by using the "is_authenticated_decorator()"
2. Define a class name User:
class User:
def __init__(self, name):
self.name = name
self.is_logged_in = False
2. The function to create a new blog post:
def create_blog_post(user):
print(f"This is {user.name}'s new blog post.")
3. Define a decorator:
To check whether users log in or not
Remember the create_blog_post function requires a param name user.
With Decorator, we cannot send param directly, in this case, we can use *args and **kwars.
args[0] means the first argument input.
def is_authenticated_decorator(function):
def wrapper(*args, **kwargs):
user = args[0]
if user.is_logged_in:
function(user)
else:
print("Please log in!")
return wrapper
4. Main Flow:
# If is_logged_in = True, a new blog post will be created.
new_user = User("Anvo0000")
new_user.is_logged_in = True
create_blog_post(new_user)
# --> This is Anvo0000's new blog post.
# If no log-in:
new_user.is_logged_in = False
create_blog_post(new_user)
# --> Please log in!
P/S: if the function has a return value, remember to return that result in a wrapper.
def logging_decorator(function):
def wrapper(*args):
result = function(*args)
print(f"You called {function.__name__}{args}")
print(f"It returned: {result}")
return result # IMPORTANT: remember to return a result for the follower function.
return wrapper
@logging_decorator
def sum_function(*args):
return sum(args)
sum_function(1,2,3)