In addition to object-oriented programming, Python also supports an
approach called Aspect-Oriented Programming.
Object-oriented programming focuses on structure and behavior of
individual objects. Aspect-oriented programming refines object design
techniques by defining aspects which are common across a number of classes
or methods.
The focus of aspect-oriented programming is consistency. Toward this
end Python allows us to define "decorators" which we can apply to class
definitions and method definitions and create consistency.
We have to note that decorators can easily be overused. The issue is
to strike a balance between the obvious programming in the class
definition and the not-obvious programming in the decorator. Generally,
decorators should be transparently simple and so obvious that they hardly
bear explanation.
Semantics of Decorators
Essentially, a decorator is a function. The purpose of a decorator
function is to transform one function definition (the argument function)
into another function definition. When you apply a decorator to a
function definition, Python creates the argument function, then applies
the decorator function to the argument function. The object returned by
the decorator is the net effect of a decorated definition. It should be
a function or object that behaves like a function.
When we say
@theDecorator
def someFunction( anArg ):
pass # some function body
We are doing the following:
We define an argument function,
someFunction.
We modify the argument function with the decorator. Python
will apply the decorator function,
theDecorator, to the argument function. The
decorator returns a value; this should be some kind of callable
object, either a class with a __call__
method or a function.
Python binds the result of the decorator to the original
function name, someFunction.
Generally, decorators fall into a number of common
categories.
Additionally, we may want to create a class function which
applies to the class as a whole. To declare this kind of method
function, the built-in
@classmethod decorator can be
used.
Debugging. There are several popular decorators to help with debugging.
Decorators can be used to automatically log function arguments,
function entrance and exit. The idea is that the decorator "wraps"
your method function with additional statements to record details
of the method function.
One of the more interesting uses for decorators is to
introduce some elements of type safety into Python. The Python Wiki
page shows decorators which can provide some type checking for
method functions where this is essential.
Additionally, Python borrows the concept of
deprecation from Java. A deprecated function
is one that will be removed in a future version of the module, class
or framework. We can define a decorator that uses the Python
warnings module to create warning messages
when the deprecated function is used.
Handling Database Transactions. In some frameworks, like Django (https://www.djangoproject.org),
decorators are used to simplify definition of database
transactions. Rather than write explicit statements to begin and
end a transaction, you can provide a decorator which wraps your
method function with the necessary additional processing.
Authorization. Web Security stands on several legs; two of those legs are
authentication and authorization. Authentication is a serious
problem involving transmission and validation of usernames and
passwords or other credentials. It's beyond the scope of this
book. Once we know who the user is, the next question is what are
they authorized to do? Decorators are commonly used web frameworks
to specify the authorization required for each function.
Published under the terms of the Open Publication License