Learning decorators is usually one of the first 'a-hah!' moments in the experience of someone coming to python from another language. The wonders of the yield statement often follow. Here's the obligatory link to 'A Curious Course on Coroutines and Concurrency' which is an excellent introduction to one of Python's most unknown yet useful features. As he puts it, they are similar to 'lightweight classes' that you can use to encapsulate state and send messages to. In the video, he starts with generators, and eventually ends up with an entire operating system (scheduler, syscalls, etc...) based on coroutines.
Decorators take a function and return a new function. 9 times out of 10 they're used as an easy way to create wrappers: do something and then execute the original function, or execute the original function and then process it before handing it off.
They're doubly useful in Python because Python has only limited support for functions as blocks.