0% completed
Python - Decorators
On This Page
First-Class Objects
Why We Need Decorators
Example: Decorator with Parameters
Handling Return Values and Arguments
Example: Decorator Handling Arguments and Return Values
Chaining Decorators
Example: Chaining Logging and Type Checking Decorators
Use Case: Web Application Routing
Example
In this lesson, we explore the functionality of decorators in Python, starting with understanding how functions in Python can be treated as first-class objects. We will demonstrate this with simple examples and then explore why decorators are essential for enhancing the functionality of functions without altering their core definition.
First-Class Objects
Functions in Python are first-class objects, meaning they can be passed around and used as arguments just like any other object.
Example: Assigning Functions to Variables
This example shows how to assign a function to a variable:
Explanation:
def greet():defines a simple function that prints a greeting.greet_func = greetassigns thegreetfunction to the variablegreet_func.greet_func()calls the function using the new variable name, demonstrating that the function behaves like an object.
Example: Passing Functions as Arguments
Functions can be passed as arguments to other functions:
Explanation:
shoutandwhisperfunctions change the case of the text.explainfunction takes another function and a string, applies the function to the string, and prints the result.explain(shout, "Hello")andexplain(whisper, "Hello")demonstrate dynamic function passing.
Why We Need Decorators
Decorators provide a way to modify functions using other functions without changing the function's source code. This capability is particularly useful for adding features like logging, access control, memoization, and more.
Example: A Simple Logging Decorator
Here’s a basic decorator that adds logging functionality to any function it decorates:
Explanation:
def logger(func):Theloggerfunction defines the decorator acceptingfunc, the function to be decorated.- Inside
logger,wrapperis defined which encapsulates the added functionality. Before calling thefunc, it logs "Logging execution...", then callsfunc(), and logs "Done logging." after the function executes. @loggeris used to apply the decorator to thesamplefunction. Whensample()is called, it first executes the logging statements, then the original function body.
Example: Decorator with Parameters
This example shows a decorator that accepts parameters, allowing for more dynamic behavior:
Explanation:
def repeat(times):This is a decorator factory that takestimesas an argument, which specifies how many times the decorated function should be repeated.decorator_repeat(func):Defines the actual decorator that wraps the functionfunc.wrapper(*args, **kwargs):The wrapper function that repeats the function call as many times as specified bytimes. It accepts any number of positional and keyword arguments to pass tofunc.- Each iteration logs the function name and iteration number before calling
func.
Handling Return Values and Arguments
When a function that returns values or takes arguments is decorated, the decorator must be properly designed to handle these aspects.
Example: Decorator Handling Arguments and Return Values
Here is a decorator that performs type checking for function arguments:
Explanation:
type_checkis applied tosum_numbers. It ensures that every argument passed tosum_numbersis an integer.- If any argument is not an integer, it raises a
ValueError. - If all arguments are integers, it calls the function and returns the result.
Chaining Decorators
Applying multiple decorators to a function is known as chaining. Each decorator adds its layer of functionality in the order specified.
Example: Chaining Logging and Type Checking Decorators
Here, both logging and type checking functionalities are added to a function:
Explanation:
@type_checkis applied first and sits closest to the function.@loggerwraps the result, so at call time the log line prints first and the type check runs after it.- The log line says
wrapper, notmultiply, becauseloggerreceives thewrapperfunction thattype_checkreturned. A plain wrapper hides the original function's name and docstring. Adding@functools.wraps(func)above eachwrappercopies them over. - The function multiplies the input numbers if all checks pass.
Use Case: Web Application Routing
Decorators are extensively used in web frameworks to map URLs to functions that generate web pages:
Example
Explanation:
-
Initialization: An empty dictionary named
routesis created. This dictionary will be used to store URL paths as keys and corresponding functions as values. -
Decorator Definition: A function named
routeis defined. This function takes a path as an argument and returns a decorator function. -
Decorator Usage: The
routedecorator is used to associate specific URL paths with functions. For example,@route("/home")associates the/homeURL path with thehome_pagefunction, and@route("/about")associates the/aboutURL path with theabout_pagefunction. -
Function Definition: Functions like
home_pageandabout_pageare defined. These functions represent the content of different pages of a hypothetical website. -
Request Simulation: The
simulate_requestfunction is defined to simulate a web request to a specified path. It takes a path as an argument and prints the result of executing the function associated with that path. -
Execution: The
simulate_requestfunction is called twice, once with the/homepath and once with the/aboutpath. This simulates visiting the home page and the about page of the simulated website, respectively. -
Output: The content of the requested pages is printed to the console.
Decorators thus serve as powerful tools for enhancing and organizing Python code, especially in complex applications where modularity, reusability, and cleanliness are crucial.
Reading Progress
0%
On This Page
First-Class Objects
Why We Need Decorators
Example: Decorator with Parameters
Handling Return Values and Arguments
Example: Decorator Handling Arguments and Return Values
Chaining Decorators
Example: Chaining Logging and Type Checking Decorators
Use Case: Web Application Routing
Example