The purpose of a Python decorator is to replace a function or method with a modified version at the time it is defined. For example, the original way to declare a static method was like this:
def someMethod(x, y):
...
someMethod = staticmethod(someMethod)
Using Python's decorator syntax, you can get the same effect like this:
@staticmethod
def someMethod(x, y):
...
In general, a function or method may be preceded by any number of decorator expressions, and you may also provide arguments to the decorators.
If a function is preceded by a decorator expression of
the form “f@”, it is the equivalent of this code:
d
deff(...): ...f=d(f)
You may provide a parenthesized argument list after
the name of your decorator. A decorator expression
is
the equivalent of this code:
d(...)
deff(...): ...f=d(...)(f)
First, the decorator is called with the argument list you provided. It must return a callable object. That callable is then called with one argument, the decorated function. The name of the decorated function is then bound to the returned value.
If you provide multiple decorators, they are applied inside out, in sequence from the last to the first.
Here is an example of a function wrapped with two decorators, of which the second has additional arguments:
@f1
@f2('Pewty')
def f0(...):
...
This is the equivalent code without using decorators:
def f0(...):
...
f0 = f1 ( f2('Pewty') ( f0 ) )
First function f2 is called with one
argument, the string 'Pewty'. The return
value, which must be callable, is then called with f0 as its argument. The return value from that
call is then passed to f1. Name f0 is then bound to the return value from the
call to f1.