What Does a Decorator Look Like? – Visual Guide & Examples (Python 2026)

Writing Functions Mar 16, 2026

What Does a Decorator Look Like? – Visual Guide & Examples (Python 2026)

A decorator in Python is a function that wraps another function to add extra behavior. Visually, decorators are easy to spot because they are placed directly above the function definition using the @ symbol.

TL;DR — How a Decorator Looks

  • Starts with @ followed by the decorator name
  • Placed immediately above the def line
  • Can be stacked (multiple decorators)
  • Can accept parameters (decorator factory)

1. Basic Decorator – Simple Look


@timer                  # ← This is how a decorator looks
def slow_task():
    import time
    time.sleep(1)
    return "Done"

# The code above is equivalent to:
def slow_task():
    ...
slow_task = timer(slow_task)   # Manual wrapping

2. Decorator with Parameters – Factory Look


@repeat(5)              # ← Decorator with arguments
@log_execution          # ← Multiple decorators (stacked)
def process_data(data):
    return [x * 2 for x in data]

# Execution order (bottom to top):
# 1. process_data is first wrapped by log_execution
# 2. Then the result is wrapped by repeat(5)

3. Real-World Decorator Examples (How They Look)


# 1. Timing decorator
@timer
def heavy_computation(n: int):
    ...

# 2. Authentication decorator
@require_login
def get_user_profile(user_id: int):
    ...

# 3. Caching decorator
@cache(ttl=300)
def fetch_from_api(endpoint: str):
    ...

# 4. Multiple decorators
@log_execution
@validate_input
@retry(max_attempts=3)
def call_external_service(payload):
    ...

4. Visual Structure Summary

  • @decorator_name → Simple decorator
  • @decorator_name(arg1, arg2) → Decorator with parameters
  • Multiple @ lines one after another → Stacked decorators
  • Decorators are applied from bottom to top

Conclusion

In Python 2026, decorators are instantly recognizable by the @ symbol placed directly above a function definition. They provide a clean, readable way to add behavior such as logging, timing, authentication, caching, and validation without modifying the original function code.

Next steps:

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices