12.1 Decorators as higher-order functions
The core idea of a decorator is to transform some original function into a new function. Used like this, a decorator creates a composite function based on the decorator and the original function being decorated.
A decorator can be used in one of the two following ways:
As a prefix that creates a new function with the same name as the base function, as follows:
@decorator def base_function() -> None: pass
As an explicit operation that returns a new function, possibly with a new name:
def base_function() -> None: pass base_function = decorator(base_function)
These are two different syntaxes for the same operation. The prefix notation has the advantages of being tidy and succinct. The prefix location is also more visible to some readers. The suffix notation is explicit and slightly more flexible.
While the prefix notation is common, there is one reason for using...