Decorators
A decorator is any callable Python object that is used to modify a function, method or class definition. A decorator is passed the original object being defined and returns a modified object, which is then bound to the name in the definition. Python decorators were inspired in part by Java annotations, and have a similar syntax; the decorator syntax is pure syntactic sugar, using @
as the keyword:
is equivalent to
def menu_item: print("spam") menu_item = viking_chorus(menu_item)Decorators are a form of metaprogramming; they enhance the action of the function or method they decorate. For example, in the above sample, viking_chorus
might cause menu_item
to be run 8 times (see Spam sketch) for each time it is called:
Canonical uses of function decorators are for creating class methods or static methods, adding function attributes, tracing, setting pre- and postconditions, and synchronisation, but can be used for far more besides, including tail recursion elimination, memoization and even improving the writing of decorators.
Decorators can be chained by placing several on adjacent lines:
@invincible @favorite_color("Blue") def black_knight: passis equivalent to
def black_knight: pass black_knight = invincible(favorite_color("Blue")(black_knight))or, using intermediate variables
def black_knight: pass blue_decorator = favorite_color("Blue") decorated_by_blue = blue_decorator(black_knight) black_knight = invincible(decorated_by_blue)In the above example, the favorite_color
decorator factory takes an argument. Decorator factories must return a decorator, which is then called with the object to be decorated as its argument:
This would then decorate the black_knight
function such that the color, "Blue", would be printed prior to the black_knight
function running.
In Python prior to version 2.6, decorators apply to functions and methods, but not to classes. Decorating a (dummy) __new__
method can modify a class, however. Class decorators are supported starting with Python 2.6.
Despite the name, Python decorators are not an implementation of the decorator pattern. The decorator pattern is a design pattern used in statically typed object-oriented programming languages to allow functionality to be added to objects at run time; Python decorators add functionality to functions and methods at definition time, and thus are a higher-level construct than decorator-pattern classes. The decorator pattern itself is trivially implementable in Python, because the language is duck typed, and so is not usually considered as such.
- See also
- Advice in Lisp.
Read more about this topic: Python Syntax And Semantics