Decorators Enhancing Functions and Methods#

Decorator = Add superpowers WITHOUT changing code @log_transaction β†’ Auto logs + validates + times

Python frameworks LIVE on decorators = $180K+ mastery


🎯 Decorators = Automatic Superpowers#

Decorator

Adds

Business Win

Lines Saved

@log

Auto logging

Audit trail

100x

@validate

Input checks

Never crash

Infinite

@timer

Performance

Optimize slow code

50x

@cache

Memoization

1000x faster

Production

@permission

Access control

Enterprise security

$1M safe


πŸš€ Step 1: YOUR First Decorator (Run this!)#

# DECORATOR = Function wrapper (Magic!)
def log_transaction(func):
    def wrapper(*args, **kwargs):
        print(f"πŸ“ LOG: Calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"πŸ“ LOG: {func.__name__} completed")
        return result
    return wrapper

# APPLY MAGIC!
@log_transaction  # ← DECORATOR!
def add_purchase(customer, amount):
    customer.spend += amount
    print(f"βœ… {customer.name}: +${amount:,}")

class Customer:
    def __init__(self, name, spend=0):
        self.name = name
        self.spend = spend

# MAGIC HAPPENS AUTOMATICALLY!
alice = Customer("Alice", 2000)
add_purchase(alice, 1200)  # Logs + purchase = FREE!

Output:

πŸ“ LOG: Calling add_purchase
βœ… Alice: +$1,200
πŸ“ LOG: add_purchase completed

πŸ”₯ Step 2: Method Decorators = Class Superpowers#

def validate_positive(func):
    def wrapper(self, amount):
        if amount <= 0:
            raise ValueError(f"{amount} must be positive!")
        return func(self, amount)
    return wrapper

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    @validate_positive  # ← AUTO VALIDATION!
    def deposit(self, amount):
        self.balance += amount
        print(f"πŸ’³ {self.owner}: +${amount:,} (Balance: ${self.balance:,.0f})")

    @validate_positive
    def withdraw(self, amount):
        if self.balance < amount:
            raise ValueError("Insufficient funds!")
        self.balance -= amount
        print(f"πŸ’Έ {self.owner}: -${amount:,}")

# NEVER CRASHES + CLEAN CODE!
account = BankAccount("Bob", 5000)
account.deposit(2000)      # βœ… Works
# account.deposit(-100)    # 🚨 Auto caught!
account.withdraw(3000)     # βœ… Works

⚑ Step 3: @timer = Performance Detective#

import time
from functools import wraps

def timer(func):
    @wraps(func)  # Preserves original name/doc
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"⏱️  {func.__name__}: {end-start:.3f}s")
        return result
    return wrapper

class Inventory:
    def __init__(self):
        self.products = {}

    @timer
    def add_bulk_products(self, product_list):
        """Simulate slow operation"""
        time.sleep(1)  # Fake slow DB
        for name, price in product_list:
            self.products[name] = price
        return len(self.products)

# PERFORMANCE MAGIC!
inventory = Inventory()
products = [("Laptop", 1200), ("Phone", 800), ("Tablet", 500)]
count = inventory.add_bulk_products(products)
print(f"βœ… Added {count} products")

Output:

⏱️  add_bulk_products: 1.002s
βœ… Added 3 products

🧠 Step 4: Multiple Decorators = STACKED Superpowers#

def log_transaction(func):
    @wraps(func)
    def wrapper(self, amount):
        print(f"πŸ’³ TRANSACTION START: {func.__name__}")
        result = func(self, amount)
        print(f"πŸ’³ TRANSACTION COMPLETE")
        return result
    return wrapper

def validate_positive(func):
    @wraps(func)
    def wrapper(self, amount):
        if amount <= 0:
            raise ValueError("Amount must be positive!")
        return func(self, amount)
    return wrapper

class PaymentProcessor:
    def __init__(self):
        self.total_processed = 0

    @log_transaction      # Bottom β†’ Top execution
    @validate_positive    # Stacked superpowers!
    def process_payment(self, amount):
        self.total_processed += amount
        print(f"βœ… Processed ${amount:,}")
        return True

# STACKED MAGIC!
processor = PaymentProcessor()
processor.process_payment(2500)

Output:

πŸ’³ TRANSACTION START: process_payment
βœ… Processed $2,500
πŸ’³ TRANSACTION COMPLETE

πŸ“Š Step 5: ENTERPRISE Decorator Suite#

# PRODUCTION DECORATOR LIBRARY
def enterprise_suite(func):
    @timer
    @log_transaction
    @validate_positive
    @wraps(func)
    def wrapper(self, amount):
        return func(self, amount)
    return wrapper

class EnterpriseAccount:
    def __init__(self, owner):
        self.owner = owner
        self.balance = 0

    @enterprise_suite  # ALL SUPERPOWERS!
    def transfer(self, amount):
        self.balance += amount
        print(f"🌟 {self.owner}: +${amount:,}")

# FULL ENTERPRISE!
account = EnterpriseAccount("CorpX")
account.transfer(10000)

πŸ“‹ Decorator Cheat Sheet#

Decorator

Code

Adds

Business Use

Log

@log_transaction

Audit trail

Compliance

Validate

@validate_positive

Input safety

Never crash

Timer

@timer

Performance

Optimization

Cache

@lru_cache

Speed

API calls

Permission

@requires_role

Security

Enterprise

# PRO TIP: Stack from bottom β†’ top!
@timer
@log
@validate
def business_method():
    ...
# Runs: validate β†’ log β†’ timer

πŸ† YOUR EXERCISE: Build YOUR Decorator Suite#

# MISSION: Create YOUR enterprise decorators!

import time
from functools import wraps

# 1. YOUR LOG DECORATOR
def your_log_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"πŸ” START: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"πŸ” END: {func.__name__}")
        return result
    return wrapper

# 2. YOUR TIMER DECORATOR
def your_timer_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"⏱️  {func.__name__}: {time.time()-start:.3f}s")
        return result
    return wrapper

# 3. YOUR BUSINESS CLASS
class YourBusinessClass:
    def __init__(self, name):
        self.name = name
        self.value = 0

    @your_log_decorator      # YOUR decorator!
    @your_timer_decorator    # YOUR decorator!
    def add_value(self, amount):
        self.value += amount
        print(f"βœ… {self.name}: +${amount:,}")
        return self.value

# TEST YOUR DECORATORS!
biz = YourBusinessClass("MyCompany")
biz.add_value(5000)

YOUR MISSION:

  1. Complete YOUR 2 decorators

  2. Test stacked magic

  3. Screenshot β†’ β€œI write enterprise decorators!”


πŸŽ‰ What You Mastered#

Skill

Status

Business Power

Decorator syntax

βœ…

Magic wrappers

Method decorators

βœ…

Class superpowers

@wraps

βœ…

Pro preservation

Stacked decorators

βœ…

Multiple powers

Enterprise suite

βœ…

$180K mastery


Next: Class Interactions (Bank β†’ Account β†’ Transaction = Full systems!)

print("🎊" * 20)
print("DECORATORS = ENTERPRISE MAGIC UNLOCKED!")
print("πŸ’» @log @timer @validate = $180K framework skill!")
print("πŸš€ Django/Flask built on THESE EXACT patterns!")
print("🎊" * 20)

can we appreciate how @validate_positive just added bulletproof input validation to every method without touching a single line of business logic? Your students went from manual if amount > 0: hell to stacked @log @timer @validate suites that power Django enterprise frameworks. While junior devs copy-paste validation 50 times, your class is writing @enterprise_suite once and applying everywhere. This isn’t decorator syntaxβ€”it’s the $180K+ framework magic that scales Netflix’s 1B+ API calls without crashes!

# Your code here