0% found this document useful (0 votes)
4 views

[Revision] Decorator in Python

A decorator in Python is a design pattern that allows adding new functionality to existing functions without modifying their structure. It is useful for changing function behavior, such as logging or caching, and can be created by defining an outer function that wraps the original function. Decorators can also accept arguments, allowing for more flexible functionality.

Uploaded by

pankajbirla4gb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

[Revision] Decorator in Python

A decorator in Python is a design pattern that allows adding new functionality to existing functions without modifying their structure. It is useful for changing function behavior, such as logging or caching, and can be created by defining an outer function that wraps the original function. Decorators can also accept arguments, allowing for more flexible functionality.

Uploaded by

pankajbirla4gb
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

decorator

in python

let's talk about


decorator in python

danial soleimany 1-15


LET'S
START
what is decorator?
A decorator is a design pattern in Python that
allows a user to add new functionality to an
existing object without modifying its structure.

When to Use a Decorator?


We use it when we need to change the behavior
of a function without modifying the function
itself. A few good examples are when you want
to add logging, test performance, perform
caching, verify permissions, and so on. We can
also use one when you need to run the same
code on multiple functions. This avoids you
writing duplicating code.

danial soleimany 2-15


To get a better understanding of
how decorators work, you should
understand a few concepts first.

danial soleimany 3-15


A function is an object
Because of that, a function can be assigned to a variable. The
function can be accessed from that variable.

def func():
return 'I am a function.'

# Assign the function to a variable without parenthesis. We don't


want to execute the function.
description = func

# Accessing the function from the variable we assigned it to.


print(description())

# Output
'I am a function.'

danial soleimany 4-15


A function can be nested within another function
def outer_function():
def inner_function():
print('I came from the inner function.')

# Executing the inner function inside the outer function.


inner_function()

outer_function()

# Output
'I came from the inner function.'

Note that the inner_function is not available outside the outer_function. If we try to
execute the inner_function outside the outer_function, we receive a NameError exception.

inner_function()

# Output
Traceback (most recent call last):
File "/tmp/my_script.py", line 9, in <module>
inner_function()
NameError: name 'inner_function' is not defined

danial soleimany 5-15


function can be returned
Since a function can be nested inside another function, it can also
be returned.

def outer_function():
'''Assign task to student'''
task = 'Programming'
def inner_function():
print(task)
return inner_function

homework = outer_function()
homework()

# Output
'Programming'

danial soleimany 6-15


function can be passed to another function as argument

def friendly_reminder(func):
'''Reminder for husband'''
func()
print('Don\'t forget to bring your wallet!')

def action():
print('I am going to the store buy you something nice.')

# Calling the friendly_reminder function with the action function


used as an argument.
friendly_reminder(action)

# Output
'I am going to the store buy you something nice.'
"Don't forget to bring your wallet!"

danial soleimany 7-15


How to create
a decorator?

danial soleimany 8-15


To create a decorator function in Python, we create an outer
function that takes a function as an argument. There is also an
inner function that wraps around the decorated function

Here is the syntax for a basic Python decorator:

def decorator_func(func):
def wrapper_func():
# Do something before the function.
func()
# Do something after the function.
return wrapper_func

@decorator_func
def original_func():
pass

To use a decorator ,you attach it to a function like you see in the


above code. We use a decorator by placing the name of the
decorator directly above the function we want to use it on. You
prefix the decorator function with an @ symbol.

danial soleimany 9-15


Here is a simple example. This decorator logs the date and time
a function is executed
from datetime import datetime
def log_datetime(func):
'''Log the date and time of a function'''
def wrapper():
print(f'Function: {func.__name__}\nRun on: {datetime.today().strftime("%Y-%m-%d %H:%M:%S")}')
result = func() # Call the original function and store its result
return result # Return the result obtained from the original function

return wrapper

@log_datetime
def daily_backup():
print('Daily backup job has finished.')
daily_backup()

# Output
'Function: daily_backup'
'Run on: 2023-08-19 20:45:11'
'Daily backup job has finished.'

danial soleimany 10-15


How to Add Arguments to Decorators?

danial soleimany 11-15


Decorators can have arguments passed to them. To add
arguments to decorators we add *args and **kwargs to the inner
functions.
*args will take an unlimited number of arguments of any type,
such as 10, True, or 'Danial'.
**kwargs will take an unlimited number of keyword arguments,
such as count=99, is_authenticated=True, or name='Danial'.
Here is a decorator with arguments:
def decorator(func):
def wrapper(*args, **kwargs):
for i in args:
print(i)
for k, v in kwargs.items():
print(k, v)
result = func(*args, **kwargs)
return result

return wrapper

@decorator
def original(a, b, c=None):
return a, b, c
original(1, 2, c=3)
1
#Output 2
c3
danial soleimany 12-15
Explanation of Code:
1. def decorator(func): This defines a decorator named decorator. It takes a single
argument, which is the function to be decorated.
2. Inside the decorator:
def wrapper(*args, **kwargs): This defines a wrapper function that will replace the
original function. The *args and **kwargs syntax allows the wrapper to accept any
number of positional and keyword arguments.
for i in args: This loop iterates through the positional arguments (args) passed to
the original function and prints each argument.
for k, v in kwargs.items(): This loop iterates through the keyword arguments
(kwargs) passed to the original function and prints both the keyword and its
associated value.
result = func(*args, **kwargs): This calls the original function (func) with the
provided arguments and keyword arguments, capturing its return value in the
result variable.
return result: The wrapper returns the result obtained from the execution of the
original function.
3. return wrapper: This line returns the wrapper function, which will replace the original
function when the decorator is applied.
4. @decorator: This is a decorator application. It means that the decorator is applied to
the following function, modifying its behavior.
5. def original(a, b, c=None): This defines a function named original that takes three
arguments: a, b, and an optional keyword argument c.
6. return a, b, c: This is the return statement of the original function. It returns a tuple
containing the values of the arguments a, b, and c.
7. original(1, 2, c=3): This line calls the original function with the arguments 1, 2, and c=3.
Due to the @decorator application, the original function is actually replaced with the
wrapper function defined within the decorator.

danial soleimany 13-15


You can also check a simple
example of decorator in my Github:

authentication system
for a web application

danial soleimany 14-15


follow
for more

danial soleimany 15-15

You might also like