Reading Time: 2 minutesDecorator Design Pattern in Python
Decorator Design Pattern in Python
Design Patterns Home
What is it?
The Decorator Design Pattern gives us a method to add new functionality to an object, dynamically. Python makes implementing this pattern relatively easier as compared to other languages, due to its builtin feature called decorators. It is a Structural Design Pattern as it eases the application design by identifying a simple way to add features to an existing object dynamically.
Why the need for it: Problem Statement
If you to add new features to an existing object without having to modify it, then you can opt for the Decorator Pattern.
Terminology
-
- Decorator function: The decorator function takes an object, manipulates it using its own object and returns this latter object. For example, in the event of decorating a function:
def decoratorFunction(inputFunction): |
def manipulateInputFunction(): |
capture return value of inputFunction |
return manipulatedReturnValueOfInputFunction |
return manipulateInputFunction |
def functionToBeDecorated(): |
returns an object , say a string |
SIGNIFICANCE OF @ NOTATION |
Any call to functionToBeDecorated() BECOMES call to decoratorFunction() with functionToBeDecorated as its argument i.e. |
functionToBeDecorated() BECOMES decoratorFunction(functionToBeDecorated)() |
stringOne = functionToBeDecorated() |
stringOne = decoratorFunction(functionToBeDecorated)() |
Pseudo Code
Following is an example of pseudo code that decorates a function. The decorator function decorateMyFunction() takes a function as input and its return value is also a function. Before beginning, it is important to understand that functions, like everything else in Python, is an object.
def decorateMyFunction(originalFunction): |
obtain string returned by original function |
def functionToBeDecorated(): |
print ( functionToBeDecorated() ) |
How to implement it
Let's make the output of a function fancier by wrapping its return value with additional text. We will make use of the decorator annotation (@) provided by Python.
def decorateMyFunction(originalFunction): |
textFromOriginalFunction = originalFunction() |
return "<p>" + textFromOriginalFunction + "</p>" |
def functionToBeDecorated(): |
print ( functionToBeDecorated() ) |
Walkthrough of implementation
- The function declared after the @decorateMyFunction gets passed to the decorateMyFunction as argument.
- So, a call to functionToBeDecorated() becomes a call to decorateMyFunction(functionToBeDecorated).
- The decorateMyFunction() method returns the function called addAdditionalText. So, the addAdditionalText() function is called.
- The addAdditionalText() function captures the return value of the function supplied to it i.e. functionToBeDecorated(), and adds additional text to it.
- This manipulated string is returned and is eventually printed.
Related to: Adapter, Composite & Strategy
See also: