What are the decorators in python with examples
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.
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.
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 aPerson
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.)