What are the decorators in python with examples

Yolanda 53 Published: 10/30/2024

What are the decorators in python with examples

I'd be happy to explain decorators in Python, along with some practical examples.

What is a Decorator?

In Python, a decorator is a special type of function that can modify or extend the behavior of another function. A decorator is a small piece of code that "wraps" around another function, adding additional functionality before and/or after the original function executes.

The Syntax

A decorator is defined using the @ symbol followed by the name of the decorator function. For example:

def my_decorator(func):

def wrapper(*args, **kwargs):

print("Something is happening before the function is called.")

result = func(*args, **kwargs)

print("Something is happening after the function is called.")

return result

return wrapper

@my_decorator

def add(a, b):

return a + b

In this example, my_decorator is the decorator function, and add is the original function that we're decorating. When we apply the decorator to the add function using the @ symbol, Python will execute the wrapper function (defined inside my_decorator) instead of the original add function.

Practical Examples

Let's explore some real-world examples of decorators in action:

Logging Function Calls: Sometimes it's useful to keep track of when certain functions are called and what arguments they receive. We can create a decorator that logs this information for us:
def log_calls(func):

def wrapper(*args, **kwargs):

print(f"{func.name} was called with arguments: {args}, {kwargs}")

return func(*args, **kwargs)

return wrapper

@log_calls

def add(a, b):

return a + b

print(add(2, 3)) # Output: "add was called with arguments: (2, 3), {}"

In this example, the log_calls decorator logs when the add function is called and what arguments it receives.

Error Handling: Sometimes we want to catch and handle exceptions that occur within a function. We can create a decorator that catches and handles exceptions for us:
def try_except(func):

def wrapper(*args, **kwargs):

try:

return func(*args, **kwargs)

except Exception as e:

print(f"An error occurred: {e}")

return wrapper

@try_except

def divide(a, b):

return a / b

print(divide(4, 0)) # Output: "An error occurred: division by zero"

In this example, the try_except decorator catches and handles any exceptions that occur when calling the divide function.

Caching: We can create a decorator that caches the results of a function to avoid redundant computations:
def memoize(func):

cache = dict()

def wrapper(*args, **kwargs):

key = str(args) + str(kwargs)

if key in cache:

return cache[key]

result = func(*args, **kwargs)

cache[key] = result

return result

return wrapper

@memoize

def fib(n):

if n <= 1:

return n

return fib(n-1) + fib(n-2)

print(fib(10)) # Only calculates the first few Fibonacci numbers

In this example, the memoize decorator caches the results of the fib function to avoid recalculating the same values multiple times.

These are just a few examples of the many creative ways you can use decorators in Python. With practice and patience, you'll become more comfortable using decorators to make your code more efficient, readable, and maintainable!

What are the famous decorators in Python?

I'd be happy to respond in English!

Python is a popular programming language known for its simplicity and ease of use. One of its key features is its extensive library collection, which includes many useful modules for data analysis, machine learning, web development, and more.

Decorators are a type of function that can modify the behavior of another function. They're often used to implement aspects or behaviors that would be repeated throughout your code. Python has several decorators that can simplify your code and make it easier to read and maintain.

Here are some of the most famous decorators in Python:

@property: This decorator is used to create getter and setter methods for attributes in a class. For example, if you have a Person class with an age attribute, you can use this decorator to create a property that allows you to get or set the age.
class Person:

def init(self, name):

self.name = name

self._age = 0

@property

def age(self):

return self._age

@age.setter

def age(self, value):

if value < 0:

raise ValueError("Age cannot be negative")

self._age = value

p = Person("John")

print(p.age) # Output: 0

p.age = 30

print(p.age) # Output: 30

@functools.lru_cache: This decorator is used to cache the results of a function, which can significantly speed up performance by avoiding redundant calculations.
import functools

@functools.lru_cache(maxsize=None)

def fibonacci(n):

if n <= 1:

return n

return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10)) # Output: 55

@singledispatch: This decorator is used to define a single function that can be applied to multiple types of input.
from functools import singledispatch

@singledispatch

def greet(obj):

if isinstance(obj, str):

return f"Hello, {obj}!"

elif isinstance(obj, int):

return "Hello, world!"

print(greet("John")) # Output: Hello, John!

print(greet(123)) # Output: Hello, world!

@contextmanager: This decorator is used to create a context manager that can be used with the with statement.
from contextlib import contextmanager

@contextmanager

def my_context():

print("Entering my context")

try:

yield

finally:

print("Exiting my context")

with my_context():

pass # Output: Entering my context; Exiting my context

@timed: This decorator is used to time how long a function takes to execute.
import time

def timed(func):

def wrapper(*args, **kwargs):

start_time = time.time()

result = func(*args, **kwargs)

end_time = time.time()

print(f"{func.name} took {end_time - start_time:.2f} seconds")

return result

return wrapper

@timed

def example_function():

time.sleep(1)

example_function() # Output: example_function took 1.00 seconds

These are just a few examples of the many decorators available in Python. By using these decorators, you can create more robust and efficient code that's easier to read and maintain.

(Note: This response is written entirely in English.)