Start here. This is the direct spoken answer to practice first.
Overview
Decorators are concise callable transformations, but that concision can hide important runtime behavior.
A decorator takes a function or class and returns the object that should replace it. @audit above a function is roughly assignment of audit(original) to that function name when the definition executes. A function decorator often returns a wrapper closure that runs behavior before or after calling the original. functools.wraps copies important metadata and exposes the wrapped function, helping introspection, documentation, and frameworks understand it.