Decorators can be used to ensure that something is executed when you enter and exit a function, but in some cases, you might want to ensure that something is always executed at the beginning and end of a block of code without having to move it to its own function or without rewriting those parts that should be executed every time.
Context managers exist to solve this need, factoring out code that you would have to rewrite over and over in place of try:except:finally:
clauses.
The most common usage of context managers is probably the closing context manager, which ensures that files get closed once the developer is done working with them, but the standard library makes it easy to write new ones.