# Jimmc414 Claude Code Plugin Marketplace Apply Decorator Wrap

> apply-decorator-wrap

- Skill: `tomevault-io/jimmc414-claude-code-plugin-marketplace-apply-decorator-wrap` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/jimmc414-claude-code-plugin-marketplace-apply-decorator-wrap`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/jimmc414-claude-code-plugin-marketplace-apply-decorator-wrap/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/jimmc414-claude-code-plugin-marketplace-apply-decorator-wrap

---


# apply-decorator-wrap

## When to Use
- Adding caching/memoization
- Timing function execution
- Logging function calls
- Input validation
- Retry logic
- Any cross-cutting concern

## When NOT to Use
- Behavior is specific to one function
- Would obscure function's purpose
- Simple inline code is clearer

## The Pattern

Decorators wrap functions to add behavior before, after, or around the original.

```python
def timing(func):
    """Decorator to time function execution."""
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(f"{func.__name__} took {elapsed:.3f}s")
        return result
    return wrapper

@timing
def slow_function():
    time.sleep(1)
    return "done"

# Equivalent to: slow_function = timing(slow_function)
```

## Example (from pytudes)

```python
# Memoization decorator (ngrams.py)
def memo(f):
    """Memoize function f."""
    table = {}

    def fmemo(*args):
        if args not in table:
            table[args] = f(*args)
        return table[args]

    fmemo.memo = table  # Expose cache
    return fmemo

@memo
def segment(text):
    """Optimal word segmentation."""
    if not text:
        return []
    candidates = ([first] + segment(rest)
                  for first, rest in splits(text))
    return max(candidates, key=word_prob)

# Using functools for cleaner decorators
from functools import cache, lru_cache, wraps

@cache  # Built-in memoization
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

@lru_cache(maxsize=1000)  # Limited cache size
def expensive_lookup(key):
    ...

# Reusable decorator with parameter
cache = lru_cache(None)  # Alias for unlimited cache

@cache
def expressions(numbers):
    ...

@cache
def segment(text):
    ...
```

## Key Principles
1. **Wrapper preserves signature**: Use `@functools.wraps`
2. **Return wrapper**: Decorator returns the wrapped function
3. **Expose internals**: Attach cache/state as attribute
4. **Stack decorators**: Multiple decorators apply bottom-up
5. **Decorator factories**: `@lru_cache(n)` returns decorator

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/jimmc414) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-13 -->

