What are Decorators?
Decorators are functions that modify other functions or classes. They use the @ syntax and are a powerful way to add functionality without modifying the original code.
Basic Decorator
Create a simple decorator:
def my_decorator(func):
def wrapper():
print("Before function")
func()
print("After function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Before function
# Hello!
# After function
Decorator with Arguments
Handle functions with parameters:
def smart_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
result = func(*args, **kwargs)
print(f"Result: {result}")
return result
return wrapper
@smart_decorator
def add(a, b):
return a + b
print(add(3, 5)) # Calling add, Result: 8, 8
Built-in Decorators
Python provides several built-in decorators:
class MyClass:
@staticmethod
def static_method():
return "Static method"
@classmethod
def class_method(cls):
return f"Class: {cls}"
@property
def my_property(self):
return "Property value"
Decorator with Parameters
Create decorators that accept arguments:
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Prints 3 times
Common Use Cases
- Timing: Measure function execution time
- Logging: Log function calls
- Caching: Store function results
- Validation: Check function arguments
- Authentication: Verify user permissions
Best Practices
- Use functools.wraps: Preserve function metadata
- Keep decorators simple: Don't add too much complexity
- Document decorators: Explain what they do
- Test decorators: Ensure they work correctly
Next Steps
Learn about generators and context managers.