# Decorator Basics — Python Fundamentals: From Basics to Async

Source: https://www.skillbyai.com/en/python/py-decorators-basics

> Wrap functions with decorators to add behaviour without changing their code, using @ syntax and *args.

## @decorator syntax

A decorator takes a function, returns a new wrapped function. `@decorator` above a `def` is shorthand for `func = decorator(func)`.

```python
def shout(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

@shout
def greet(name):
    return f"hello, {name}"

print(greet("ada"))   # HELLO, ADA
```

## Wrapping, not changing

A decorator is like **gift wrapping** — the function inside is unchanged, but it now comes with extra behaviour around it.
